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

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条)

相关推荐 更多相似问题