首页 > 解决方案 > Spring Security 返回 WWW-Authenticate 标头并在禁用 httpBasic 时显示 http 基本窗口

问题描述

我的 webflux 服务器有安全配置:

    @Bean
    fun httpTestFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
        http
            .authorizeExchange()
            .pathMatchers("/actuator/**").permitAll()
            .pathMatchers("/webjars/swagger-ui/**", "/v3/api-docs/**").permitAll()
            .anyExchange().access(authManager)
            .and().cors()
            .and()
            .httpBasic().disable()
            .formLogin().disable()
            .csrf().disable()
            .logout().disable()

        return http.build()
    }

    @Bean
    fun userDetailsService(): ReactiveUserDetailsService {
        val user: UserDetails = User.builder()
            .username(userName)
            .password(passwordEncoder().encode(password))
            .roles("ADMIN")
            .build()
        return MapReactiveUserDetailsService(user)
    }

    @Bean
    fun passwordEncoder() = BCryptPasswordEncoder()

    @Bean("CustomAuth")
    fun authManager(): 
    ReactiveAuthorizationManager<AuthorizationContext> {
        return ReactiveAuthorizationManager<AuthorizationContext> { mono, context ->
            val request = context.exchange.request
            val mutateExchange = context.exchange.mutate()

            val token = request.headers[AUTHORIZATION] ?: throw 
            AccessDeniedException(ERROR_MESSAGE)

            mono
                // go to other service to check token
                .then(webClient.checkToken(token.first().toString()))
                .doOnError {
                    throw AccessDeniedException(ERROR_MESSAGE)
                }
                .cast(ResponseEntity::class.java)
                .map { it.body as AuthDto }
                .doOnNext { auth ->
                    mutateExchange.request {
                        it.header(USER_ID, auth.userId.toString())
                        it.header(AUTH_SYSTEM, auth.authSystem)
                    }
                }
                .map { AuthorizationDecision(true) }
        }
    }

如您所见,httpBasic() 选项已禁用。当我转到任何安全 url 时,浏览器会显示 http 基本窗口。然后我可以输入有效或无效的登录名和密码,如果 authManager 返回良好的结果,则身份验证将成功,否则在其他情况下将抛出 401,并且浏览器中的身份验证窗口将重新打开。

为什么会发生?是虫子吗?

PS Spring boot 2.5.5版

标签: spring-securityspring-webflux

解决方案


推荐阅读