为集成Okta的Keycloak JWT Token添加角色至Principal/Token
Keycloak集成Okta后权限注解无法生效的解决方案
背景说明
- 已在Keycloak 10.0.0中通过OpenId Connect v1.0配置Okta作为身份提供商,用户通过Keycloak登录并获取其生成的JWT Token
- 平台内用户由管理员创建,角色存储在Keycloak;Okta SSO用户首次登录时仅在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); }
Token角色差异
- 平台内用户的Keycloak Token中
realm_access字段包含角色信息:
"realm_access": { "roles": [ "offline_access", "ROLE_MANAGER", "uma_authorization" ] }
- Okta用户的Token仅包含基础角色:
"realm_access": { "roles": [ "offline_access", "uma_authorization" ] }
问题与需求
- 上述差异导致无法使用
@PreAuthorize("hasRole('ROLE_PM')")等注解对Okta用户进行权限控制 - 需要从数据库获取角色并添加到Okta用户的Keycloak Token或Principal中,使Controller方法可正常使用权限注解
- 已找到相关扩展方案,但该方案改写了Token认证逻辑,担心存在安全风险,不确定是否可用于生产环境
内容的提问来源于stack exchange,提问作者Tusar
相关产品推荐
相关产品推荐

