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

时间:2015-11-04 01:53:18

标签: spring-security spring-boot spring-security-oauth2 spring-social spring-cloud

我正在实施一个需要提供OAuth2令牌授权并支持多种社交服务(google +,facebook等)的spring启动应用程序。用户应该能够选择他喜欢的社交网络并使用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主类注释为@ EnableOAuth2Sso。

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

谢谢你的时间,

克里斯

4 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:1)

确实,请查看马里奥发布的链接(不确定为什么会被投票...):social_login_manual

链接说@ 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

答案 2 :(得分:0)

我还偶然发现了这个以及有关多个身份验证提供程序支持的许多其他问题。 Syer的回答是,核心@EnableOAuth2Sso注释并未针对此进行设计实际上非常有用。它让我看向其他地方。

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

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

基本上,根据SecurityConfiguration中DelegatingAuthenticationProviderEndpoint做出的决定(在默认包上)选择提供程序。 AuthenticationProcessingFilter正在等待身份验证事件并重定向到身份验证提供程序。返回时,它会验证收到的代码并带有AuthenticationToken自定义AuthenticationProvider进行评估。

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

希望这有帮助。

答案 3 :(得分:0)

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

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

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