【问题标题】:Disable webflux (reactive) security for actuator health endpoint禁用执行器健康端点的 webflux(反应式)安全性
【发布时间】:2019-12-28 01:37:02
【问题描述】:

我有一个包含 WebFlux、Health actuator 和 Spring security 的项目。我正在尝试构建自定义身份验证,但该身份验证也适用于健康执行器端点。如何禁用它?

根据文档,我实现了一个自定义 ServerSecurityContextRepository,这是它看起来有点像的基本版本:

@Component
class MySecurityContextRepository: ServerSecurityContextRepository {
    override fun save(exchange: ServerWebExchange?, context: SecurityContext?) = Mono.empty()

    override fun load(exchange: ServerWebExchange) = Mono.error(ResponseStatusException(HttpStatus.UNAUTHORIZED, "Access denied"))
}

根据文档,我不应该被要求做任何额外的配置来禁用健康端点上的身份验证。这是来自application.yml的配置:

management:
  metrics:
        web:
          server:
            auto-time-requests: true
            requests-metric-name: xxx-xxx-xxx
        export:
          statsd:
            enabled: xxxx
            host: xxxxxxxxxxxx
            flavor: xxx
  endpoint:
      health:
        enabled: true
  endpoints:
      web:
          base-path: /application

这不起作用,因为我从 /application/health 端点看到了 401。所以我也将它添加到我的安全配置中:

@EnableWebFluxSecurity
class SecurityConfig @Autowired constructor(
        private val myRepository: MySecurityContextRepository
) {
    @Bean
    fun securityWebFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
        http.securityContextRepository(myRepository)
        http.authorizeExchange()
                .pathMatchers("/application/health").permitAll()
                .anyExchange().permitAll()

        http.cors().disable()
        http.csrf().disable()
        http.formLogin().disable()

        return http.build()
    }
}

尽管添加此操作 curl http://localhost:8080/application/health/ 会导致 {"name":"xxxxxx","message":"Unknown Error","response":"401 UNAUTHORIZED \"Access denied\""} 并且状态代码也是 401。如何禁用对我的健康端点的授权?

【问题讨论】:

    标签: spring-boot spring-security spring-boot-actuator


    【解决方案1】:

    所以在没有帮助之后,我开始查看源代码,结果发现ServerSecurityContextRepository 总是为HealthEndpointInfoEndpoint 调用,所以我自己添加了跳过存储库中的身份验证检查的逻辑。您可以轻松做到:

    val HEALTH_ENDPOINTS = EndpointRequest.to(HealthEndpoint::class.java, InfoEndpoint::class.java)
    

    现在您可以执行以下操作:

                return HEALTH_ENDPOINTS.matches(exchange).flatMap { matches ->
                    if (matches.isMatch) {
                        Mono.just(SecurityContextImpl(GuestAuthToken))
                    } else {
                        Mono.empty()
                    }
                }
    

    这样我就不会在我的存储库中硬编码任何路径。这并不理想,但可以完成工作。

    【讨论】:

      【解决方案2】:

      最好使用EndpointRequest 来匹配执行器端点,因为它会匹配您的配置。使用反应式导入(不是 servlet)。

      application.yml:

      management:
        endpoint:
            health:
              enabled: true
        endpoints:
          web:
            base-path: /application
      

      WebSecurityConfig.java:

      @Configuration
      @EnableWebFluxSecurity
      public class WebSecurityConfig {
          @Bean
          public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
              return http.csrf().disable()
                      .authorizeExchange()
                      .matchers(EndpointRequest.to("health")).permitAll()
                      .and().build();
          }
      }
      

      【讨论】:

        【解决方案3】:

        关于 spring docu 29.2 WebFlux Security 你只需要添加:

        import org.springframework.boot.autoconfigure.security.reactive.PathRequest;
        import org.springframework.context.annotation.Bean;
        import org.springframework.context.annotation.Configuration;
        import org.springframework.security.config.web.server.ServerHttpSecurity;
        import org.springframework.security.web.server.SecurityWebFilterChain;
        
        @Configuration
        public class WebFluxSecurityConfigurer {
        
            @Bean
            public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
                return http
                        .authorizeExchange()
                        .pathMatchers("/status/**")
                        .permitAll().and()
                        .build();
            }
        }
        

        不要忘记添加所有可能的路径,例如 ../health 和 ../health/ 或者使用通配符更好

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-07-08
          • 2019-03-30
          • 2020-11-16
          • 2020-06-17
          • 1970-01-01
          • 2019-03-10
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多