Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/hadoop/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SpringCloudGateway重定向到KeyClope登录页面,尽管设置了承载令牌_Spring_Spring Security_Keycloak_Spring Security Oauth2_Keycloak Rest Api - Fatal编程技术网

SpringCloudGateway重定向到KeyClope登录页面,尽管设置了承载令牌

SpringCloudGateway重定向到KeyClope登录页面,尽管设置了承载令牌,spring,spring-security,keycloak,spring-security-oauth2,keycloak-rest-api,Spring,Spring Security,Keycloak,Spring Security Oauth2,Keycloak Rest Api,我正在使用一个设置,其中keydove作为身份提供者,springcloudgateway作为API网关和多个微服务。 我可以通过http://localhost:8050/auth/realms/dev/protocol/openid-连接/令牌 我可以使用JWT访问直接位于KeyClope服务器上的资源(例如http://localhost:8080/auth/admin/realms/dev/users)。 但是当我想使用网关将我中继到同一资源时(http://localhost:8050

我正在使用一个设置,其中keydove作为身份提供者,springcloudgateway作为API网关和多个微服务。 我可以通过
http://localhost:8050/auth/realms/dev/protocol/openid-连接/令牌

我可以使用JWT访问直接位于KeyClope服务器上的资源(例如
http://localhost:8080/auth/admin/realms/dev/users
)。 但是当我想使用网关将我中继到同一资源时(
http://localhost:8050/auth/admin/realms/dev/users
)我得到了KeyClope登录表单作为响应

我的结论是,我的SpringCloudGateway应用程序中肯定存在配置错误

这是网关中的安全配置:

@Configuration
@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
public class SecurityConfiguration {

    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http, ReactiveClientRegistrationRepository clientRegistrationRepository) {

        // Authenticate through configured OpenID Provider
        http.oauth2Login();

        // Also logout at the OpenID Connect provider
        http.logout(logout -> logout.logoutSuccessHandler(
                new OidcClientInitiatedServerLogoutSuccessHandler(clientRegistrationRepository)));

        //Exclude /auth from authentication
        http.authorizeExchange().pathMatchers("/auth/realms/ahearo/protocol/openid-connect/token").permitAll();

        // Require authentication for all requests
        http.authorizeExchange().anyExchange().authenticated();

        // Allow showing /home within a frame
        http.headers().frameOptions().mode(Mode.SAMEORIGIN);

        // Disable CSRF in the gateway to prevent conflicts with proxied service CSRF
        http.csrf().disable();
        return http.build();
    }
}
spring:
  application:
    name: gw-service
  cloud:
    gateway:
      default-filters:
        - TokenRelay
      discovery:
        locator:
          lower-case-service-id: true
          enabled: true
      routes:
        - id: auth
          uri: http://localhost:8080
          predicates:
            - Path=/auth/**

  security:
    oauth2:
      client:
        registration:
          keycloak:
            client-id: 'api-gw'
            client-secret: 'not-relevant-but-correct'
            authorizationGrantType: authorization_code
            redirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}'
            scope: openid,profile,email,resource.read
        provider:
          keycloak:
            issuerUri: http://localhost:8080/auth/realms/dev
            user-name-attribute: preferred_username

server:
  port: 8050
eureka:
  client:
    service-url:
      default-zone: http://localhost:8761/eureka
    register-with-eureka: true
    fetch-registry: true
这是网关中的my application.yaml:

@Configuration
@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
public class SecurityConfiguration {

    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http, ReactiveClientRegistrationRepository clientRegistrationRepository) {

        // Authenticate through configured OpenID Provider
        http.oauth2Login();

        // Also logout at the OpenID Connect provider
        http.logout(logout -> logout.logoutSuccessHandler(
                new OidcClientInitiatedServerLogoutSuccessHandler(clientRegistrationRepository)));

        //Exclude /auth from authentication
        http.authorizeExchange().pathMatchers("/auth/realms/ahearo/protocol/openid-connect/token").permitAll();

        // Require authentication for all requests
        http.authorizeExchange().anyExchange().authenticated();

        // Allow showing /home within a frame
        http.headers().frameOptions().mode(Mode.SAMEORIGIN);

        // Disable CSRF in the gateway to prevent conflicts with proxied service CSRF
        http.csrf().disable();
        return http.build();
    }
}
spring:
  application:
    name: gw-service
  cloud:
    gateway:
      default-filters:
        - TokenRelay
      discovery:
        locator:
          lower-case-service-id: true
          enabled: true
      routes:
        - id: auth
          uri: http://localhost:8080
          predicates:
            - Path=/auth/**

  security:
    oauth2:
      client:
        registration:
          keycloak:
            client-id: 'api-gw'
            client-secret: 'not-relevant-but-correct'
            authorizationGrantType: authorization_code
            redirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}'
            scope: openid,profile,email,resource.read
        provider:
          keycloak:
            issuerUri: http://localhost:8080/auth/realms/dev
            user-name-attribute: preferred_username

server:
  port: 8050
eureka:
  client:
    service-url:
      default-zone: http://localhost:8761/eureka
    register-with-eureka: true
    fetch-registry: true

我如何使网关能够知道用户已通过身份验证(使用JWT),而不将我重定向到登录页面?

我通过直接与Key斗篷通信绕过了这个问题,而无需通过Spring Cloud Gateway向其转发请求


这实际上不是一个解决方法,但实际上是最佳实践/据我所知完全没有问题。

如果您想使用访问令牌向Spring Gateway发出请求,则需要将其设置为资源服务器。添加以下内容:

pom.xml

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
    </dependency>
SecurityConfiguration.java

@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http,
                                                        ReactiveClientRegistrationRepository clientRegistrationRepository) {
    // Authenticate through configured OpenID Provider
    http.oauth2Login();
    // Also logout at the OpenID Connect provider
    http.logout(logout -> logout.logoutSuccessHandler(
            new OidcClientInitiatedServerLogoutSuccessHandler(clientRegistrationRepository)));
    // Require authentication for all requests
    http.authorizeExchange().anyExchange().authenticated();

    http.oauth2ResourceServer().jwt();

    // Allow showing /home within a frame
    http.headers().frameOptions().mode(Mode.SAMEORIGIN);
    // Disable CSRF in the gateway to prevent conflicts with proxied service CSRF
    http.csrf().disable();
    return http.build();
}

您能告诉我您是如何绕过登录页面实现此功能的吗?将其更改为:授权授予类型:授权\代码您是否能够绕过登录页面?如果是,请与我们分享如何?您可以请分享一些源代码吗?不需要代码,只需直接寻址您的KeyClope服务器。因此,与其(让API将您的请求重定向到keydove),不如使用(直接将请求发送到keydove实例)?请看最后的评论