Spring Security Spring安全性返回WWW-Authenticate报头,并在禁用httpBasic时显示http basic窗口

8mmmxcuj  于 2022-12-18  发布在  Spring
关注(0)|答案(1)|浏览(350)

我有我的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()选项被禁用。当我进入任何安全的网址,浏览器显示http基本窗口。然后我可以输入有效或无效的登录名和密码,如果authManager返回良好的结果,身份验证将成功或401将抛出在其他情况下,浏览器中的身份验证窗口将重新打开。
为什么会这样?是虫子吗?
P.S. Spring Boot 版本2.5.5

lpwwtiir

lpwwtiir1#

解决方案帮助了我:

@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。然后返回更改后的响应。

相关问题