Spring Cloud Gateway总是返回HTTP状态503,如何解决?

bkk*_*bkk 5 spring-boot spring-cloud spring-cloud-gateway

我正在尝试将 Spring Cloud Gateway 与 Spring Security 结合使用。但不幸的是,看起来安全性并不重要,所有请求都经过其目的地,或者至少尝试经过。只是尝试一下,因为我每次都会收到 HTTP 状态 503。我在 Spring 5,并尝试尽可能地“反应”。我究竟做错了什么?当服务尝试使用功能区负载平衡查找目的地时,日志中没有任何有趣的内容,只有常见的行。我还启用了网关服务器上的访问日志,希望能得到一些额外的信息,但什么也没有。

我已经简化了我的代码,这是不起作用的最小配置。

POM依赖和依赖管理:

    <dependencies>
        <!-- Spring Cloud Gateway service -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

        <!-- Spring Cloud Eureka client -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <!-- Spring Cloud config client -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- Spring Security -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
Run Code Online (Sandbox Code Playgroud)

bootstrap.yml:

spring:
  application:
    name: gateway-server
  cloud:
    config:
      name: gateway-server
      username: configUser
      password: configPassword
      discovery:
        enabled: true
        service-id: config-server
eureka:  
  client:
    serviceUrl:
      defaultZone: http://discUser:discPassword@localhost:9002/eureka/
  instance:
    leaseRenewalIntervalInSeconds: 1
    leaseExpirationDurationInSeconds: 2
Run Code Online (Sandbox Code Playgroud)

安全配置:

spring:
  application:
    name: gateway-server
  cloud:
    config:
      name: gateway-server
      username: configUser
      password: configPassword
      discovery:
        enabled: true
        service-id: config-server
eureka:  
  client:
    serviceUrl:
      defaultZone: http://discUser:discPassword@localhost:9002/eureka/
  instance:
    leaseRenewalIntervalInSeconds: 1
    leaseExpirationDurationInSeconds: 2
Run Code Online (Sandbox Code Playgroud)

网关路由定义:

@Configuration
@EnableWebFluxSecurity
public class SecurityConfig  {

    private static final Logger LOGGER = LoggerFactory.getLogger(SecurityConfig.class);

    @Bean
    public ReactiveUserDetailsService userDetailsService() {
        UserDetails user1 = User.withDefaultPasswordEncoder()
            .username("discUser")
            .password("discPassword")
            .roles("SYSTEM", "USER")
            .build();

        return new MapReactiveUserDetailsService(user1);
    }

    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
        LOGGER.info("TEMP_LOG: Test");
            return http
                .csrf()
                    .disable()
                .httpBasic()
                    .and()
                .authorizeExchange()
                    .pathMatchers("/eureka/**")
                        .hasRole("SYSTEM")
                    .pathMatchers("/eureka/css/**", "/eureka/js/**")
                        .permitAll()
                            .and()
                .build();
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我从浏览器调用网关服务(没有任何用户名),我会期望一个登录表单,或者至少是一个 403,因为我没有定义用户,因此安全性无法真正完成其工作。

但我只得到错误后备页面说:

2019 年 3 月 31 日星期日 11:46:42 UTC 发生意外错误(类型 = 服务不可用,状态 = 503)。未找到该服务或项目。

如果我从命令行调用该网关,例如使用curl,如下所示:

curl --user discUser:discPassword http://localhost:8080/eureka

然后我得到同样的错误。

任何帮助,将不胜感激!