同时为多个社交网络启用 OAuth2Sso

EnableOAuth2Sso simultaneously for multiple social networks

我正在实施 spring 启动应用程序,需要提供 OAuth2 令牌授权并支持多种社交服务(google+、facebook 等)。用户应该能够 select 他喜欢的社交网络并使用 OAuth2 授权框架登录。 我正在使用此处描述的方法 http://cloud.spring.io/spring-cloud-security/ 来实现上述内容。

目前我的application.yml看起来像这样

spring:
  oauth2:
    client:
      clientId: {{my app's google id}
      clientSecret: {{my app's google secret code}} 
  etc...

此外,spring boot main class 被注释为 @EnableOAuth2Sso。

我的问题是,通过上述方法,我只能使用一个社交网络(示例中为 google+)。所以,我想知道是否有办法通过在 .yml 文件中以某种方式定义它们来同时支持多个社交网络。 这是可能的还是我应该使用其他方法?

感谢您的宝贵时间,

克里斯

@EnableOAuth2Sso 功能并非旨在支持多个提供程序作为简单的 YAML 声明。而不是使用它,您需要在安全配置中安装 2 个单独的 OAuth2AuthenticationProcessingFilters,每个都有不同的登录路径,然后 link 从 UI.

到它们

我也偶然发现了这个问题以及许多其他有关多身份验证提供程序支持的问题。 Syer 的回答是核心 @EnableOAuth2Sso 注释不是为此设计的,这实际上非常有帮助。它让我转向别处。

受益于 Nimbus OAuth 库,我设计了另一种方法。它可能不干净也不漂亮,但它符合我的计划。单独的身份验证提供程序在属性中定义并根据 URI 路径选择。

这是我想出的:https://bitbucket.org/klaalo/orcidconnect/src/f3e4fada9827e47bd33efd579fd020c41e37ee2a/src/main/java/fi/csc/orcidconnect/oauth2client/

基本上,提供商是根据 DelegatingAuthenticationProviderEndpoint 在 SecurityConfiguration(在默认包上)中做出的决定来选择的。 AuthenticationProcessingFilter 正在等待身份验证事件并重定向到身份验证提供程序。在 return 上,它将验证收到的代码并携带 AuthenticationToken 以供自定义 AuthenticationProvider 评估。

收到的 UserDetails 保存到 Map 中的 User 对象。

希望对您有所帮助。

您提供的 link 仅展示了如何使用启用单个身份验证服务器提供程序的 @EnableOAuth2Sso 工具。为了实现多个提供程序,您应该遵循:

https://spring.io/guides/tutorials/spring-boot-oauth2/#_social_login_manual

并为每个提供商实施过滤器。

确实,请查看 Mario 发布的 link(不知道为什么它被否决了..):social_login_manual

link 说 @EnableOAuth2Sso 本质上是 @EnableOAuth2Client 和一些额外魔法的组合。缺点是您无法轻松自定义其行为以支持多个提供商。因此,在本教程中,建议将其替换为 @EnableOAuth2Client,并重复 @EnableOAuth2Sso 在幕后所做的一些自定义添加。

所以,这是它的样子:

@SpringBootApplication
@EnableOAuth2Client
@RestController
public class SocialApplication extends WebSecurityConfigurerAdapter {

   private Filter ssoFilter() {
      CompositeFilter filter = new CompositeFilter();
      List<Filter> filters = new ArrayList<>();
      filters.add(ssoFilter(facebook(), "/login/facebook"));
      filters.add(ssoFilter(github(), "/login/github"));
      filter.setFilters(filters);
      return filter;
    }



 private Filter ssoFilter(ClientResources client, String path) {
      OAuth2ClientAuthenticationProcessingFilter filter = new OAuth2ClientAuthenticationProcessingFilter(path);
      OAuth2RestTemplate template = new OAuth2RestTemplate(client.getClient(), oauth2ClientContext);
      filter.setRestTemplate(template);
      filter.setTokenServices(new UserInfoTokenServices(
          client.getResource().getUserInfoUri(), client.getClient().getClientId()));
      return filter;
    }

  @Bean
    @ConfigurationProperties("github")
    public ClientResources github() {
      return new ClientResources();
    }

  @Bean
    @ConfigurationProperties("facebook")
    public ClientResources facebook() {
      return new ClientResources();
    }

}

class ClientResources {

  @NestedConfigurationProperty
  private AuthorizationCodeResourceDetails client = new AuthorizationCodeResourceDetails();

  @NestedConfigurationProperty
  private ResourceServerProperties resource = new ResourceServerProperties();

  public AuthorizationCodeResourceDetails getClient() {
    return client;
  }

  public ResourceServerProperties getResource() {
    return resource;
  }
}

facebook:
  client:
    clientId: 233668646673605
    clientSecret: 33b17e044ee6a4fa383f46ec6e28ea1d
    accessTokenUri: https://graph.facebook.com/oauth/access_token
    userAuthorizationUri: https://www.facebook.com/dialog/oauth
    tokenName: oauth_token
    authenticationScheme: query
    clientAuthenticationScheme: form
  resource:
    userInfoUri: https://graph.facebook.com/me
github:
  client:
    clientId: bd1c0a783ccdd1c9b9e4
    clientSecret: 1a9030fbca47a5b2c28e92f19050bb77824b5ad1
    accessTokenUri: https://github.com/login/oauth/access_token
    userAuthorizationUri: https://github.com/login/oauth/authorize
    clientAuthenticationScheme: form
  resource:
    userInfoUri: https://api.github.com/user