Luk*_*Luk 6 spring spring-security spring-security-ldap spring-boot spring-security-oauth2
我们有一个基于Spring Boot的微服务架构,在该架构中,我们有多个相互对话的微服务以及一个连接到不同微服务的Javascript UI。
由于这是一个内部应用程序,并且我们需要将它们连接到SAML2端点以提供SSO,因此将所有这些连接在一起让我有些头疼。理想情况下,微服务在其自身(JWT)和UI之间使用oAuth2,但是用户身份验证是通过SAML2完成的
我要实现以下目标:
所以我尝试了很多不同的东西。我能说的是:
我想我最麻烦的是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);
}
}
Run Code Online (Sandbox Code Playgroud)
而且效果很好。因此,当我命中一个受保护的端点时,我将被重定向并可以通过saml登录。然后在samlUserDetailsService中获取用户详细信息。
关于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);
}
}
Run Code Online (Sandbox Code Playgroud)
这部分也可以与其他具有@EnableResourceServer的micorservices一起使用
据我了解的OAuth部分,ClientDetailsServiceConfigurer只是配置客户端应用程序(在我的情况下为其他微服务),对此我应该使用client_credentials类的授予(但不确定)。但是我不清楚如何连接SAML部分...
作为替代方案,我正在考虑将其拆分。创建一个微服务,它是一个OAuth授权服务,另一个是执行SAML位的服务。在这种情况下,如果用户通过了身份验证,则SAML微服务将连接到SAML并提供类似/ me的终结点。然后,OAuth授权服务将使用SAML微服务来检查用户是否在那里进行了身份验证,并且在这种情况下提供令牌。对于刷新令牌,我也将这样做。据我了解,我将在公共void configure(ClientDetailsServiceConfigurer客户端)throws Exception {}方法中实现这种逻辑。
如果有更好的方法,请告诉我!
| 归档时间: |
|
| 查看次数: |
1734 次 |
| 最近记录: |