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,浏览器中的身份验证窗口将重新打开。

为什么会发生这种情况?是虫子吗?

p.S.弹簧引导版本2.5.5

解决方案帮助了我:

@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()
.exceptionHandling()
.authenticationEntryPoint { exchange, _ ->
val response = exchange.response
response.statusCode = HttpStatus.UNAUTHORIZED
response.headers.set(HttpHeaders.WWW_AUTHENTICATE, "None")
exchange.mutate().response(response)
Mono.empty()
}
.and()
.httpBasic().disable()
.formLogin().disable()
.csrf().disable()
.logout().disable()
return http.build()
}

我们需要在状态代码中更改authenticationEntryPoint,并禁用HttpHeaders.WWW_AUTHENTICATE。然后返回更改后的响应。

最新更新