Spring Boot 3未授权访问时重定向至Keycloak登录页配置问题
解决Keycloak + Spring Boot 3/Spring Security 6未授权请求重定向登录页问题
问题根源
你当前的配置是**OAuth2资源服务器(Resource Server)模式,仅处理Bearer Token验证,无状态设计下未授权请求默认返回401,不会触发登录重定向。要实现浏览器请求重定向到Keycloak登录页,需要同时启用OAuth2客户端(Authorization Code Flow)**模式,添加oauth2Login配置。
修改步骤
1. 更新SecurityFilterChain配置
调整安全配置,添加oauth2Login()支持登录重定向,同时修改会话策略(授权码流程需要会话保存授权状态):
import lombok.RequiredArgsConstructor; 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.config.http.SessionCreationPolicy; import org.springframework.security.web.SecurityFilterChain; @Configuration @EnableWebSecurity @EnableMethodSecurity @RequiredArgsConstructor public class SecurityConfig { private final KeycloakJwtTokenConverter keycloakJwtTokenConverter; @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(requests -> requests .anyRequest().authenticated()) // 启用OAuth2登录,处理重定向到Keycloak登录页 .oauth2Login(oauth2 -> oauth2 .defaultSuccessUrl("/", true)) // 登录成功后默认跳转路径 // 保留原有的资源服务器配置,支持Bearer Token访问API .oauth2ResourceServer(resourceServer -> resourceServer .jwt(jwt -> jwt .jwtAuthenticationConverter(keycloakJwtTokenConverter))) // 修改会话策略:授权码流程需要会话保存授权请求状态,不能用STATELESS .sessionManagement(session -> session .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)); return http.build(); } }
2. 补充application.yaml的OAuth2客户端配置
除了原有的资源服务器配置,添加客户端相关配置(替换your-client-id、your-client-secret为你在Keycloak中创建的客户端信息):
spring: security: oauth2: resourceserver: jwt: issuer-uri: http://localhost:443/realms/my-realm-name jwk-set-uri: ${spring.security.oauth2.resourceserver.jwt.issuer-uri}/protocol/openid-connect/certs # 添加OAuth2客户端配置 client: registration: keycloak: client-id: your-client-id client-secret: your-client-secret authorization-grant-type: authorization_code redirect-uri: "{baseUrl}/login/oauth2/code/keycloak" scope: openid, profile, email provider: keycloak: issuer-uri: ${spring.security.oauth2.resourceserver.jwt.issuer-uri} authorization-uri: ${spring.security.oauth2.resourceserver.jwt.issuer-uri}/protocol/openid-connect/auth token-uri: ${spring.security.oauth2.resourceserver.jwt.issuer-uri}/protocol/openid-connect/token user-info-uri: ${spring.security.oauth2.resourceserver.jwt.issuer-uri}/protocol/openid-connect/userinfo jwk-set-uri: ${spring.security.oauth2.resourceserver.jwt.issuer-uri}/protocol/openid-connect/certs user-name-attribute: preferred_username
3. Keycloak客户端配置注意事项
确保你在Keycloak的my-realm-name realm中创建的客户端满足:
- 访问类型设置为
confidential(因为需要客户端密钥) - 有效的重定向URI包含
{baseUrl}/login/oauth2/code/keycloak(比如你的应用运行在http://localhost:8080,就添加http://localhost:8080/login/oauth2/code/keycloak) - 启用
Authorization Code Flow
说明
- 同时配置
oauth2Login和oauth2ResourceServer后,你的应用既支持浏览器访问时重定向到Keycloak登录,也支持通过Bearer Token访问API端点。 - 会话策略改为
IF_REQUIRED是因为授权码流程需要临时会话保存授权请求的状态(比如state参数),登录成功后会话会保留用户信息。
内容的提问来源于stack exchange,提问作者Mortl
相关产品推荐
相关产品推荐

