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()则可正常返回资源。
看了好多博文都不知道自己到底哪里配置错了。
这个应该还要结合权限角色,前后端配合起来吧。
您好,我是有问必答小助手,您的问题已经有小伙伴解答了,您看下是否解决,可以追评进行沟通哦~
如果有您比较满意的答案 / 帮您提供解决思路的答案,可以点击【采纳】按钮,给回答的小伙伴一些鼓励哦~~
ps:问答VIP仅需29元,即可享受5次/月 有问必答服务,了解详情>>>https://vip.csdn.net/askvip?utm_source=1146287632
在Spring Cloud Security的github issue区发现了同样的问题https://github.com/spring-cloud/spring-cloud-gateway/issues/2064
那个issue的actual behavior的第6步描述了类似的事情,我猜测是tokenrelay出了点问题,目前看来只好等待开发者的回应了
非常感谢您使用有问必答服务,为了后续更快速的帮您解决问题,现诚邀您参与有问必答体验反馈。您的建议将会运用到我们的产品优化中,希望能得到您的支持与协助!
速戳参与调研>>>https://t.csdnimg.cn/Kf0y