weixin_49335538
Species8470
2021-04-29 10:59
采纳率: 100%
浏览 170
已采纳

Spring Cloud Gateway + OAuth2登录成功后无法访问被保护的资源

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()则可正常返回资源。

看了好多博文都不知道自己到底哪里配置错了。

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

4条回答 默认 最新

  • software7503
    已采纳

    这个应该还要结合权限角色,前后端配合起来吧。

    点赞 评论
  • QA_Assistant
    有问必答小助手 2021-04-29 18:44

    您好,我是有问必答小助手,您的问题已经有小伙伴解答了,您看下是否解决,可以追评进行沟通哦~

    如果有您比较满意的答案 / 帮您提供解决思路的答案,可以点击【采纳】按钮,给回答的小伙伴一些鼓励哦~~

    ps:问答VIP仅需29元,即可享受5次/月 有问必答服务,了解详情>>>https://vip.csdn.net/askvip?utm_source=1146287632

    点赞 评论
  • weixin_49335538
    Species8470 2021-04-29 19:34

    在Spring Cloud Security的github issue区发现了同样的问题https://github.com/spring-cloud/spring-cloud-gateway/issues/2064

    那个issue的actual behavior的第6步描述了类似的事情,我猜测是tokenrelay出了点问题,目前看来只好等待开发者的回应了

    点赞 评论
  • QA_Assistant
    有问必答小助手 2021-05-06 14:53

    非常感谢您使用有问必答服务,为了后续更快速的帮您解决问题,现诚邀您参与有问必答体验反馈。您的建议将会运用到我们的产品优化中,希望能得到您的支持与协助!

    速戳参与调研>>>https://t.csdnimg.cn/Kf0y

    点赞 评论

相关推荐