Spring Boot网关:禁用默认OAuth2登录页问题求助
问题解决:Spring Gateway访问/login跳转默认OAuth2登录页而非Keycloak的处理
问题背景
我正在开发一个小型项目,计划将Keycloak作为授权服务器,同时将应用作为Spring Gateway和OAuth2客户端。
问题描述
访问其他端点时,会正常重定向到Keycloak登录页,但访问端点localhost:9090/login时,会跳转到默认的OAuth2登录选择页。由于使用了oauth2 client依赖,并且采用ServerHttpSecurity而非HttpSecurity,因此无法使用如下传统配置:
httpSecurity .oauth2Login() .loginPage("/redirect");
当前配置信息
Gateway pom.xml
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.3</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>at.matkollin</groupId> <artifactId>spring-demo</artifactId> <version>1.0.0-SNAPSHOT</version> <properties> <java.version>17</java.version> <spring-cloud.version>2021.0.1</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
Gateway application.yaml
spring: security: oauth2: client: registration: keycloak-spring-gateway-client: provider: my-keycloak-provider scope: openid client-id: spring-gateway-client client-secret: xxxxxxxxxx authorization-grant-type: authorization_code redirect-uri: "{baseUrl}/login/oauth2/code/keycloak" provider: my-keycloak-provider: issuer-uri: http://172.31.0.2:8080/realms/Demo token-uri: http://172.31.0.2:8080/auth/realms/Demo/protocol/openid-connect/token authorization-uri: http://172.31.0.2:8080/auth/realms/Demo/protocol/openid-connect/auth userinfo-uri: http://172.31.0.2:8080/auth/realms/Demo/protocol/openid-connect/userinfo user-name-attribute: preferred_username server: port: 9090 management: endpoints: web: exposure: include: "*"
Security Config
@Configuration public class SecurityConfig { @Bean public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { http .authorizeExchange() .pathMatchers("/actuator/**", "/") .permitAll() .and() .authorizeExchange() .anyExchange() .authenticated() .and() .oauth2Login(); return http.build(); } }
解决方法
方法一:通过Gateway路由重定向(最简单)
在application.yaml中添加Gateway路由规则,将/login路径直接重定向到Keycloak对应的OAuth2授权入口:
spring: cloud: gateway: routes: - id: login-redirect uri: no://op predicates: - Path=/login filters: - RedirectTo=302, /oauth2/authorization/keycloak-spring-gateway-client
这样访问localhost:9090/login时,会直接跳转到Keycloak的登录页面,而不是默认的OAuth2选择页。
方法二:通过Security配置自定义认证入口
修改SecurityConfig,配置异常处理的认证入口点,让未认证请求(包括访问/login)直接跳转到Keycloak授权地址:
@Configuration public class SecurityConfig { private final ClientRegistrationRepository clientRegistrationRepository; public SecurityConfig(ClientRegistrationRepository clientRegistrationRepository) { this.clientRegistrationRepository = clientRegistrationRepository; } @Bean public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { http .authorizeExchange(exchanges -> exchanges .pathMatchers("/actuator/**", "/") .permitAll() .anyExchange() .authenticated() ) .oauth2Login(oauth2 -> oauth2 .authorizationRequestResolver(new DefaultServerOAuth2AuthorizationRequestResolver( clientRegistrationRepository, "/oauth2/authorization" )) ) .exceptionHandling(exceptions -> exceptions .authenticationEntryPoint(new RedirectServerAuthenticationEntryPoint( "/oauth2/authorization/keycloak-spring-gateway-client" )) ); return http.build(); } }
该配置会让所有需要认证的请求(包括直接访问/login)都重定向到Keycloak的登录页面。
内容的提问来源于stack exchange,提问作者Matthias Kopeinigg
相关产品推荐
相关产品推荐

