将Spring Security OAuth2与SAML SSO连接

时间:2018-02-08 15:40:32

标签: spring spring-boot spring-security spring-security-oauth2 spring-security-ldap

我们有一个基于spring boot的微服务架构,我们有多个微服务器相互通信,还有一个连接到不同微服务的Javascript UI。

由于这是一个内部应用程序,我们需要将它们连接到我们的SAML2端点以提供SSO,因此将所有这些连接起来让我感到头疼。理想情况下,微服务在它们之间使用oAuth2(JWT)和UI,但用户身份验证是通过SAML2完成的

以下我想用此实现:

  • UI客户端使用JWT
  • 与微服务对话
  • 微服务也使用JWT互相交谈。当用户向微服务发起请求并且微服务需要来自另一个微服务的更多数据时,它会使用用户JWT令牌(这应该相当容易)。
  • 拥有一个中央身份验证微服务,负责生成新令牌并根据SAML端点对用户进行身份验证。
  • 在身份验证微服务中存储一些SAML详细信息(例如角色)

所以我尝试了很多不同的东西。我可以说的是:

我想我在努力的地方是oauth2资源服务器和SAML服务的连接点。

关于SAML我有以下工作正常:

@Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Value("${security.saml2.metadata-url}")
    String metadataUrl;
    @Value("${server.ssl.key-alias}")
    String keyAlias;
    @Value("${server.ssl.key-store-password}")
    String password;
    @Value("${server.port}")
    String port;
    @Value("${server.ssl.key-store}")
    String keyStoreFilePath;

    @Autowired
    SAMLUserDetailsService samlUserDetailsService;


    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.antMatcher("/**")
                .authorizeRequests()
                .antMatchers("/oauth/**").authenticated()
                .and().exceptionHandling()

                .and()
                .authorizeRequests()
                .antMatchers("/saml*").permitAll()
                .anyRequest().authenticated()
                .and()
                .apply(saml()).userDetailsService(samlUserDetailsService)
                .serviceProvider()
                .keyStore()
                .storeFilePath("saml/keystore.jks")
                .password(this.password)
                .keyname(this.keyAlias)
                .keyPassword(this.password)
                .and()
                .protocol("https")
                .hostname(String.format("%s:%s", "localhost", this.port))
                .basePath("/")
                .and()
                .identityProvider()
                .metadataFilePath(this.metadataUrl);

    }
}

并且工作正常。因此当我点击受保护的端点时,我将被重定向并可以通过saml登录。我在samlUserDetailsS​​ervice中获得了userdetails。

关于oauth我有这样的事情:

@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.tokenStore(tokenStore())
                .tokenEnhancer(accessTokenConverter())
                .authenticationManager(authenticationManager);
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.tokenKeyAccess("permitAll()")
                .checkTokenAccess("isAuthenticated()");
    }

    @Bean
    public TokenStore tokenStore() {
        return new JwtTokenStore(accessTokenConverter());
    }


    @Bean
    JwtAccessTokenConverter accessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setSigningKey("ABC"); //needs to be changed using certificates
        return converter;
    }


    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {

        clients.inMemory()
                .withClient("acme")
                .secret("acmesecret")
                .authorizedGrantTypes("refresh_token", "authorization_code")
                .autoApprove(true)
                .scopes("webapp")
                .accessTokenValiditySeconds(60)
                .refreshTokenValiditySeconds(3600);
    }
}

这部分也适用于我有@EnableResourceServer

的其他微服务器

据我了解OAuth部分,ClientDetailsS​​erviceConfigurer只配置客户端应用程序(在我的情况下是其他微服务),我应该使用client_credentials类型的授权(但不确定)。但是我如何在SAML部分接线并不清楚......

作为替代方案,我正在考虑拆分它。创建一个OAuth授权服务的微服务和另一个执行SAML位的微服务。在这种情况下,如果用户通过身份验证,SAML微服务将连接到SAML并提供类似/ me的端点。然后,OAuth授权服务将使用SAML微服务检查用户是否在那里进行了身份验证,如果是这种情况,则提供令牌。关于刷新令牌,我也会这样做。 据我所知,我会在这个中实现这种逻辑 public void configure(ClientDetailsS​​erviceConfigurer clients)抛出Exception {}方法。

如果有更好的方法,请告诉我!

0 个答案:

没有答案