Spring Boot 3 结合 Keycloak Spring Adapter 的替代实现方案咨询
Spring Boot 3 集成 Keycloak 认证方案(替代已移除的 WebSecurityConfigurerAdapter)
Spring Boot 3 搭配的 Spring Security 6 已彻底移除 WebSecurityConfigurerAdapter,而旧版 Keycloak Spring Adapter 依赖该类,因此无法直接使用。目前官方推荐的方案是用 Spring Security 原生的 OAuth2/OIDC 支持对接 Keycloak,无需依赖旧的 Keycloak 适配器。
步骤1:替换依赖
移除旧的 keycloak-spring-boot-starter,添加 Spring Security 官方的 OAuth2 相关依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-resource-server</artifactId> </dependency>
步骤2:配置 Keycloak 连接信息
在 application.yml(或 application.properties)中配置 Keycloak 作为 OIDC 认证服务器的参数:
spring: security: oauth2: client: registration: keycloak: client-id: 你的客户端ID client-secret: 你的客户端密钥 scope: openid, profile, email authorization-grant-type: authorization_code redirect-uri: "{baseUrl}/login/oauth2/code/keycloak" provider: keycloak: # 注意:Keycloak 17+ 版本路径去掉了 /auth 前缀 issuer-uri: http://你的Keycloak服务器地址/realms/你的Realm名称 user-name-attribute: preferred_username resource-server: jwt: issuer-uri: http://你的Keycloak服务器地址/realms/你的Realm名称
步骤3:编写安全配置类
用 Spring Security 6 的新方式,通过 SecurityFilterChain Bean 替代原有的 KeycloakWebSecurityConfigurerAdapter:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.web.SecurityFilterChain; @Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http // 配置访问权限 .authorizeHttpRequests(auth -> auth .requestMatchers("/public/**", "/error").permitAll() // 公开路径 .anyRequest().authenticated() ) // 配置 OAuth2 登录(对接 Keycloak) .oauth2Login(oauth2 -> oauth2 .loginPage("/login") // 可选:自定义登录页路径 ) // 配置资源服务器(解析 Keycloak 签发的 JWT) .oauth2ResourceServer(oauth2 -> oauth2 .jwt(jwt -> jwt.jwtAuthenticationConverter(new KeycloakJwtConverter())) ); return http.build(); } }
可选:自定义 JWT 角色转换
如果需要从 Keycloak 的 JWT 中提取角色信息,可编写转换器:
import org.springframework.core.convert.converter.Converter; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.oauth2.jwt.Jwt; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class KeycloakJwtConverter implements Converter<Jwt, Collection<GrantedAuthority>> { @Override public Collection<GrantedAuthority> convert(Jwt jwt) { // 从 Keycloak JWT 的 realm_access 字段中获取角色 Map<String, Object> realmAccess = jwt.getClaim("realm_access"); if (realmAccess == null) { return List.of(); } List<String> roles = (List<String>) realmAccess.get("roles"); return roles.stream() .map(role -> new SimpleGrantedAuthority("ROLE_" + role)) .collect(Collectors.toList()); } }
注意事项
- 旧版 Keycloak Spring Adapter 已被官方废弃,不再支持 Spring Boot 3,必须切换到原生 OAuth2/OIDC 方案
- 建议使用 Keycloak 20+ 版本,确保与 Spring Boot 3 兼容
- Keycloak 17+ 版本的
issuer-uri路径不再包含/auth前缀,配置时注意对应
内容的提问来源于stack exchange,提问作者Samuel
相关产品推荐
相关产品推荐

