Keycloak 18与Spring Boot 2.7.2集成报错求助及示例需求
Keycloak 18 与 Spring Boot 2.7.2 集成示例
你的启动错误核心原因是Keycloak 18+ 移除了默认的/auth上下文路径,原来配置里的http://localhost:48080/auth/realms/XXX/.well-known/openid-configuration路径已失效,正确路径应为http://localhost:48080/realms/XXX/.well-known/openid-configuration。以下是完整可用的集成方案:
1. 依赖配置(pom.xml)
推荐使用Spring Security原生OAuth2资源服务器依赖,替代旧的Keycloak专属starter,适配性更强:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-resource-server</artifactId> </dependency> </dependencies>
2. 应用配置(application.yml)
修正Issuer路径,配置Keycloak核心参数:
spring: security: oauth2: resourceserver: jwt: issuer-uri: http://localhost:48080/realms/XXX # 替换为你的实际领域名称 jwk-set-uri: ${spring.security.oauth2.resourceserver.jwt.issuer-uri}/protocol/openid-connect/certs # 可选:开启Security调试日志,排查问题用 logging: level: org.springframework.security: DEBUG
注意:
issuer-uri只需指定到领域层级,Spring Security会自动拼接后续的openid-configuration路径。
3. Spring Security 配置类
创建配置类,保护API端点并配置JWT验证逻辑:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; 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 @EnableMethodSecurity(securedEnabled = true, prePostEnabled = true) public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth .anyRequest().authenticated() ) .oauth2ResourceServer(oauth2 -> oauth2 .jwt(jwt -> jwt .jwtAuthenticationConverter(new KeycloakJwtAuthenticationConverter()) // 可选:自定义JWT角色转换器 ) ); return http.build(); } }
可选:自定义JWT角色转换器
如果需要将Keycloak返回的realm_access.roles映射为Spring Security标准权限,添加以下转换器:
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.stream.Collectors; public class KeycloakJwtAuthenticationConverter implements Converter<Jwt, Collection<GrantedAuthority>> { @Override public Collection<GrantedAuthority> convert(Jwt jwt) { List<String> roles = jwt.getClaimAsList("realm_access.roles"); return roles.stream() .map(role -> new SimpleGrantedAuthority("ROLE_" + role)) .collect(Collectors.toList()); } }
4. 测试接口
创建带权限控制的REST接口,验证集成效果:
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class TestController { @GetMapping("/public") public String publicEndpoint() { return "Public endpoint - no auth required"; } @GetMapping("/private") public String privateEndpoint() { return "Private endpoint - authenticated users only"; } @GetMapping("/admin") @PreAuthorize("hasRole('admin')") public String adminEndpoint() { return "Admin endpoint - requires admin role"; } }
关键注意事项
- Keycloak客户端配置:确保客户端
Access Type设置为confidential(需使用client-secret时),并开启Service Accounts Enabled(服务间调用场景)。 - Docker启动Keycloak:确认启动命令未添加
--context-path /auth参数,Bitnami镜像默认已移除/auth路径,示例启动命令:docker run -p 48080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin bitnami/keycloak:18 - 令牌获取:Postman请求令牌的端点需改为
http://localhost:48080/realms/XXX/protocol/openid-connect/token,不要带/auth前缀。
内容的提问来源于stack exchange,提问作者zamek 42
相关产品推荐
相关产品推荐

