首页 > 解决方案 > 禁用执行器健康端点的 webflux(反应式)安全性

问题描述

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

根据文档,我实现了一个 custom 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-bootspring-securityspring-boot-actuator

解决方案


所以在没有帮助之后,我开始查看源代码,结果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()
                }
            }

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


推荐阅读