无Spring Boot环境下,从KeycloakWebSecurityConfigurerAdapter迁移至Spring Security 6
纯Spring环境下从KeycloakWebSecurityConfigurerAdapter迁移到Spring Security OAuth2的方案
1. 调整依赖
移除原Keycloak Spring Security适配器依赖,添加Spring Security OAuth2资源服务器及JOSE相关依赖:
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-oauth2-resource-server</artifactId> <version>6.x.x</version> <!-- 版本与Spring 6保持适配 --> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-oauth2-jose</artifactId> <version>6.x.x</version> </dependency>
2. 配置JWT解码器
创建JwtDecoder Bean,指向Keycloak的JWKS端点,用于验证和解码JWT令牌:
@Bean public JwtDecoder jwtDecoder() { String jwksUri = "http://your-keycloak-host:port/realms/your-realm/protocol/openid-connect/certs"; return NimbusJwtDecoder.withJwkSetUri(jwksUri).build(); }
3. 自定义JWT权限转换器
Keycloak的角色信息默认存放在realm_access.roles字段中,需自定义转换器将其映射为Spring Security的权限:
@Bean public JwtAuthenticationConverter jwtAuthenticationConverter() { JwtGrantedAuthoritiesConverter grantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter(); grantedAuthoritiesConverter.setAuthoritiesClaimName("realm_access.roles"); grantedAuthoritiesConverter.setAuthorityPrefix("ROLE_"); JwtAuthenticationConverter authenticationConverter = new JwtAuthenticationConverter(); authenticationConverter.setJwtGrantedAuthoritiesConverter(grantedAuthoritiesConverter); return authenticationConverter; }
4. 构建安全过滤器链
替代原KeycloakWebSecurityConfigurerAdapter,通过SecurityFilterChain配置安全规则:
@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth .requestMatchers("/public/**").permitAll() .anyRequest().authenticated() ) .oauth2ResourceServer(oauth2 -> oauth2 .jwt(jwt -> jwt .decoder(jwtDecoder()) .jwtAuthenticationConverter(jwtAuthenticationConverter()) ) ); return http.build(); }
5. 权限控制配置
可通过两种方式配置权限:
- 注解方式:在配置类上添加
@EnableMethodSecurity,然后在业务方法上使用@PreAuthorize("hasRole('ADMIN')"); - 过滤器链方式:在
authorizeHttpRequests中指定路径对应的角色,例如:
.requestMatchers("/admin/**").hasRole("ADMIN")
6. 额外配置(可选)
如果需要获取Keycloak用户信息(如用户名、邮箱),可直接从JWT令牌的Claims中提取:
Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); Jwt jwt = (Jwt) authentication.getPrincipal(); String username = jwt.getClaimAsString("preferred_username"); String email = jwt.getClaimAsString("email");
内容的提问来源于stack exchange,提问作者Julian Zenker
相关产品推荐
相关产品推荐

