Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring boot Spring Security 5(Webflux)中给定路径的Force ServerAuthenticationFailureHandler_Spring Boot_Kotlin_Spring Security_Spring Webflux - Fatal编程技术网

Spring boot Spring Security 5(Webflux)中给定路径的Force ServerAuthenticationFailureHandler

Spring boot Spring Security 5(Webflux)中给定路径的Force ServerAuthenticationFailureHandler,spring-boot,kotlin,spring-security,spring-webflux,Spring Boot,Kotlin,Spring Security,Spring Webflux,我有两条路径/foo和/bar。对于/foo,我有一个自定义的身份验证机制。在/bar上,我有基本身份验证 除了一种情况外,此设置工作正常。当我没有在/foo中传递授权标题时,将启动基本身份验证,而不是MyAuthenticationFailureHandler 是否有方法为给定路径设置MyAuthenticationFailureHandler?或者我把SecurityWebFiltersOrder搞砸了 我的完整安全配置: bean<MyReactiveUserDetailsServi

我有两条路径
/foo
/bar
。对于
/foo
,我有一个自定义的身份验证机制。在
/bar
上,我有
基本
身份验证

除了一种情况外,此设置工作正常。当我没有在
/foo
中传递
授权
标题时,将启动基本身份验证,而不是
MyAuthenticationFailureHandler

是否有方法为给定路径设置
MyAuthenticationFailureHandler
?或者我把
SecurityWebFiltersOrder
搞砸了

我的完整安全配置:

bean<MyReactiveUserDetailsService>()
bean<MyReactiveAuthenticationManager>()
bean {
    ref<ServerHttpSecurity>()
        .securityMatcher {
            if (it.request.path.value().contains("/bar")) {
                ServerWebExchangeMatcher.MatchResult.match()
            } else {
                ServerWebExchangeMatcher.MatchResult.notMatch()
            }
        }
        .formLogin().disable()
        .csrf().disable()
        .logout().disable()
        .httpBasic()
        .and()
        .authorizeExchange()
        .pathMatchers("/bar/**")
        .hasRole("ADMIN")
        .anyExchange().permitAll()
        .and()
        .build()
}

bean {
    ref<ServerHttpSecurity>()
        .securityMatcher {
            if (it.request.path.value().contains("/bar")) {
                ServerWebExchangeMatcher.MatchResult.notMatch()
            } else {
                ServerWebExchangeMatcher.MatchResult.match()
            }
        }
        .httpBasic().disable()
        .formLogin().disable()
        .csrf().disable()
        .logout().disable()
        .authorizeExchange()
        .pathMatchers(
            HttpMethod.POST,
            "/foo/**"
        ).hasRole(
            "ABRACADABRA"
        )
        .anyExchange().permitAll()
        .and()
        .addFilterAt(
            authenticationWebFilter(ref(), ref()),
            SecurityWebFiltersOrder.AUTHENTICATION
        )
        .build()
}
}

private fun authenticationWebFilter(
    reactiveAuthenticationManager: ReactiveAuthenticationManager,
    objectMapper: ObjectMapper
) =
    AuthenticationWebFilter(reactiveAuthenticationManager).apply {
        setServerAuthenticationConverter(MyAuthenticationConverter())
        setRequiresAuthenticationMatcher(
            ServerWebExchangeMatchers.pathMatchers(
                HttpMethod.POST,
               "/foo/**"
            )
        )
        setAuthenticationFailureHandler(MyAuthenticationFailureHandler(objectMapper))
    }

class MyAuthenticationConverter : ServerAuthenticationConverter {
    override fun convert(exchange: ServerWebExchange): Mono<Authentication> {
        val authHeader: String? = exchange.request.headers.getFirst(HttpHeaders.AUTHORIZATION)
        // ... 
        return when {
            isValid(authHeader, ...) -> {
                Mono.just(
                    UsernamePasswordAuthenticationToken(principal, credentials)
                )
            }
            else -> Mono.empty()
        }
    }
}

class MyAuthenticationFailureHandler(private val objectMapper: ObjectMapper) : ServerAuthenticationFailureHandler {
    override fun onAuthenticationFailure(
        webFilterExchange: WebFilterExchange,
        exception: AuthenticationException?
    ): Mono<Void> {
        val response = webFilterExchange.exchange.response
        response.apply {
            statusCode = HttpStatus.OK
            headers.contentType = MediaType.APPLICATION_JSON
            headers.set(HttpHeaders.WARNING, """199 warning "Invalid token"""")
        }

        return response.writeWith(
            Flux.just(
                DefaultDataBufferFactory().wrap(
                    objectMapper.writeValueAsBytes(
                        MyDto(
                            // ...
                        ).toSettingResponse()
                    )
                )
            )
        )
    }
}
bean()
bean()
豆子{
ref()
.securityMatcher{
if(it.request.path.value()包含(“/bar”)){
ServerWebExchangeMatcher.MatchResult.match()
}否则{
ServerWebExchangeMatcher.MatchResult.notMatch()
}
}
.formLogin().disable()
.csrf().disable()
.logout().disable()
.httpBasic()
.及()
.授权交易所()
.pathMatchers(“/bar/**”)
.hasRole(“管理员”)
.anyExchange().permitAll()
.及()
.build()
}
豆子{
ref()
.securityMatcher{
if(it.request.path.value()包含(“/bar”)){
ServerWebExchangeMatcher.MatchResult.notMatch()
}否则{
ServerWebExchangeMatcher.MatchResult.match()
}
}
.httpBasic().disable()
.formLogin().disable()
.csrf().disable()
.logout().disable()
.授权交易所()
.路径匹配者(
HttpMethod.POST,
“/foo/**”
)哈斯罗先生(
“ABRACADABRA”
)
.anyExchange().permitAll()
.及()
addFilterAt先生(
authenticationWebFilter(ref(),ref()),
SecurityWebFiltersOrder.AUTHENTICATION
)
.build()
}
}
private fun authenticationWebFilter(
reactiveAuthenticationManager:reactiveAuthenticationManager,
objectMapper:objectMapper
) =
AuthenticationWebFilter(reactiveAuthenticationManager)。应用{
setServerAuthenticationConverter(MyAuthenticationConverter())
setRequiresAuthenticationMatcher(
ServerWebExchangeMatchers.pathMatchers(
HttpMethod.POST,
“/foo/**”
)
)
setAuthenticationFailureHandler(MyAuthenticationFailureHandler(objectMapper))
}
类MyAuthenticationConverter:ServerAuthenticationConverter{
覆盖乐趣转换(exchange:ServerWebExchange):Mono{
val authHeader:String?=exchange.request.headers.getFirst(HttpHeaders.AUTHORIZATION)
// ... 
何时返回{
isValid(authHeader,…)->{
单声道(
UsernamePasswordAuthenticationToken(主体、凭据)
)
}
else->Mono.empty()
}
}
}
类MyAuthenticationFailureHandler(私有val对象映射器:对象映射器):ServerAuthenticationFailureHandler{
重写身份验证失败(
webFilterExchange:webFilterExchange,
异常:AuthenticationException?
):Mono{
val响应=webFilterExchange.exchange.response
响应。应用{
statusCode=HttpStatus.OK
headers.contentType=MediaType.APPLICATION\u JSON
headers.set(HttpHeaders.WARNING,“”199警告“无效令牌”“”“)
}
返回response.writeWith(
通量,只是(
DefaultDataBufferFactory().wrap(
objectMapper.writeValueAsBytes(
MyDto(
// ...
).toSettingResponse()
)
)
)
)
}
}

您可以使用
AuthenticationWebFilter
设置自定义
服务器AuthenticationFailureHandler

@Bean
public SecurityWebFilterChain securitygWebFilterChain(ServerHttpSecurity http) {
            AuthenticationWebFilter authenticationWebFilter = new AuthenticationWebFilter(authenticationManager);
            authenticationWebFilter.setAuthenticationFailureHandler(myAuthenticationFailureHandler) 
     return http.authorizeExchange()
                    .pathMatchers("/user/signup")
                    .permitAll().pathMatchers("/user/login")
                    .permitAll()
                    .anyExchange().authenticated()
                    .and()
                    .securityContextRepository(NoOpServerSecurityContextRepository.getInstance())
                    .addFilterAt(authenticationWebFilter, SecurityWebFiltersOrder.AUTHENTICATION)
                    .httpBasic().disable()
                    .csrf().disable()
                    .formLogin().disable()
                    .logout().disable()
                    .build();
        }

您可以使用
AuthenticationWebFilter
设置自定义
ServerAuthenticationFailureHandler

@Bean
public SecurityWebFilterChain securitygWebFilterChain(ServerHttpSecurity http) {
            AuthenticationWebFilter authenticationWebFilter = new AuthenticationWebFilter(authenticationManager);
            authenticationWebFilter.setAuthenticationFailureHandler(myAuthenticationFailureHandler) 
     return http.authorizeExchange()
                    .pathMatchers("/user/signup")
                    .permitAll().pathMatchers("/user/login")
                    .permitAll()
                    .anyExchange().authenticated()
                    .and()
                    .securityContextRepository(NoOpServerSecurityContextRepository.getInstance())
                    .addFilterAt(authenticationWebFilter, SecurityWebFiltersOrder.AUTHENTICATION)
                    .httpBasic().disable()
                    .csrf().disable()
                    .formLogin().disable()
                    .logout().disable()
                    .build();
        }