spring cloud gateway作为网关,keycloak作为认证服务器,spring boot构建了资源服务器,OAuth2的授权类型是authrization code。angular前端在访问keycloak的登录界面并成功登录后依旧无法访问被保护的资源,查看报文发现对资源请求的响应报文状态码是302,location是/oauth2/authorization/keycloak,而且无论是gateway自己的endpoint还是资源服务器的endpoint都是一样的302响应,资源服务器也没有显示收到请求。
但是如果把安全配置中的SecurityWebFilterChain从http.authorizeExchange().anyExchange().authenticated();中的authenticated()改为permitall()则资源均可正常访问。
参考的博客在这里https://www.chencanhao.com/Identity/spring-keyclack-oauth-gateway
配置基本上和博客中的一致,但是为了方便阅读还是在这里列出来。这是gateway的pom:
<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.cloud</groupId>
<artifactId>spring-cloud-security</artifactId>
</dependency>
gateway的安全配置:
public SecurityWebFilterChain springSecurityFilterChain (ServerHttpSecurity http,
ReactiveClientRegistrationRepository clientRegistrationRepository){
http.cors();
http.oauth2Login().authenticationSuccessHandler(MyServerAuthenticationSuccessHandler);
http.logout(logout -> logout.logoutSuccessHandler(
new OidcClientInitiatedServerLogoutSuccessHandler(clientRegistrationRepository)));
http.logout().logoutUrl("/auth/logout");
http.authorizeExchange().anyExchange().authenticated();
http.csrf().disable();
http.httpBasic().disable();
http.formLogin().disable();
}
application.yaml:
spring:
security:
oauth2:
client:
provider:
keycloak:
issuer-uri: http://localhost:9080/auth/realms/realmtest
user-name-attribute: preferred_username
registration:
keycloak:
client-id: client1
client-secret: ba6f5dfe-b815-4d31-a260-8ba3aed6ed49
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
allowedOrigins: "http://localhost:4200"
allowedHeaders:
- content-type
- authorization
allowedmethods:
- GET
- POST
- PUT
routes:
- id: review
uri: http://localhost:9082/review
predicates:
- Path=/review/**
filters:
- TokenRelay=
第一次登录后gateway中有显示用户的token及提取出的用户信息可知登录成功,keycloak的控制台也显示用户有active session,但是对两个资源的GET请求均返回302 Found。
这里是浏览器收到的响应报文
但是如果把安全配置中的authenticated()改为permitall()则可正常返回资源。
看了好多博文都不知道自己到底哪里配置错了。