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

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条回答 默认 最新

  • 关注

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

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

悬赏问题

  • ¥15 IAR程序莫名变量多重定义
  • ¥15 (标签-UDP|关键词-client)
  • ¥15 关于库卡officelite无法与虚拟机通讯的问题
  • ¥100 已有python代码,要求做成可执行程序,程序设计内容不多
  • ¥15 目标检测项目无法读取视频
  • ¥15 GEO datasets中基因芯片数据仅仅提供了normalized signal如何进行差异分析
  • ¥100 求采集电商背景音乐的方法
  • ¥15 数学建模竞赛求指导帮助
  • ¥15 STM32控制MAX7219问题求解答
  • ¥20 在本地部署CHATRWKV时遇到了AttributeError: 'str' object has no attribute 'requires_grad'