我已经使用 OpenId Connect v1.0 在 Keycloak (10.0.0) Identity Provider 中配置了 Okta。这样用户就可以通过 keycloak 登录,JWT 令牌将由 keycloak 生成。
在 Spring Security 中,配置如下所示
@KeycloakConfiguration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
/**
* Registers the KeycloakAuthenticationProvider with the authentication manager.
*/
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
auth.authenticationProvider(keycloakAuthenticationProvider);
}
@Bean
@Primary
public KeycloakConfigResolver keycloakConfigResolver() {
return new CustomKeycloakSpringBootConfigResolver();
}
//May be I can use NullAuthenticatedSessionStrategy here as the application is used to authorize api request only using token
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.headers().frameOptions().sameOrigin();
http.cors()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.sessionAuthenticationStrategy(sessionAuthenticationStrategy())
.and().exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint()).and().authorizeRequests()
.anyRequest().authenticated()
.and()
.csrf().disable();
}
.....
// Avoid double bean registration
//...
//registrationBean.setEnabled(false);
}
Keycloak JWT 令牌具有作用,而 Okta 令牌在 realm_access 中没有作用。所以我无法使用@PreAuthorize("hasRole('ROLE_PM')")(对于 Okta 用户它将失败)。
Keycloak(从令牌中提取):
"realm_access": {
"roles": [
"offline_access",
"ROLE_MANAGER",
"uma_authorization"
]
}
Okta 代币(摘自代币):
"realm_access": {
"roles": [
"offline_access",
"uma_authorization"
]
}
预期:扩展 Keycloak 令牌或主体以将角色从 DB 添加到 Okta 用户令牌。这样我就可以在控制器方法上使用 @PreAuthorize("hasRole('ROLE_MANAGER') 或 hasRole('ROLE_USER')")。
我找到了一个链接:在 Spring boot 中扩展 Keycloak 令牌
但是令牌认证工作被覆盖了。我不知道将来是否会有任何安全问题或者代码可以用于生产!