java - Webflux 安全登录失败处理程序不起作用
问题描述
如果登录/注销成功或失败,我正在尝试使用 Spring webflux 安全自定义字符串消息进行设置。除“authenticationFailureHandler”外,处理程序正在工作。
文档中提到了一些关于“logoutSuccessUrl()”的内容,但它不存在,并且这些处理程序返回 Mono< Void >。
所以我有两个问题:
如何返回一些字符串作为响应,例如,如果身份验证失败,则类似于“无效的用户名或密码”或一些 json 字符串。我试图重定向到一个动作,但我不能用 void Mono 来做。
为什么 authenticationFailureHandler 不起作用,而其他所有处理程序都起作用?那是一个错误吗?
-我尝试使用 Mono.just("redirect:/some-url").then() 进行重定向,但它没有做任何事情。对于回复
- 我制作了我的处理程序 bean,尝试更改方法序列,禁用/启用其他处理程序。对于 authenticationFailureHandler。
你可以在这里找到我的全部代码: https ://github.com/iron2414/WebFluxAuth
是本文代码的修改版: https ://medium.com/@mgray_94552/reactive-authorisation-in-spring-security-943e6534aaeb
安全配置如下所示:
return http
.exceptionHandling()
.accessDeniedHandler((swe, e) -> {
System.out.println("ACCESS DENIED");
return Mono.fromRunnable(() -> {
swe.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
});
})
.authenticationEntryPoint((swe, e) -> {
System.out.println("AUTHENTICATION ENTRTY POINT");
ServerHttpResponse response = swe.getResponse();
return Mono.fromRunnable(() -> {
swe.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
});
})
.and()
.authorizeExchange()
.pathMatchers("/**").authenticated()
.and()
.formLogin()
.authenticationFailureHandler(MyAuthenticationFailureHandler())
.authenticationSuccessHandler(MyAuthenticationSuccessHandler()).and()
.logout().logoutSuccessHandler(MyLogoutHandler())
.and()
.csrf()
.disable()
.build();
loginFailure 处理程序:
@Bean
public MyAuthenticationFailureHandler MyAuthenticationFailureHandler() {
return new MyAuthenticationFailureHandler();
}
@Component
public class MyAuthenticationFailureHandler implements ServerAuthenticationFailureHandler {
@Override
public Mono<Void> onAuthenticationFailure(WebFilterExchange webFilterExchange, AuthenticationException e) {
//TODO redirect
System.out.println("AUTHENTICATION FAILURE");
return Mono.empty();
}
}
解决方案
我遇到了同样的问题,最终使用自定义 DefaultErrorWebExceptionHandler 来处理它:
@Component
public class MyGlobalWebExceptionHandler extends DefaultErrorWebExceptionHandler {
@Override
protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
return route(all(), this::renderErrorResponse);
}
@Override
protected Mono<ServerResponse> renderErrorResponse(ServerRequest request) {
ErrorRepresentation representation = createErrorRepresentation(request);
return ServerResponse
.status(representation.getError().getStatus())
.contentType(APPLICATION_JSON_UTF8)
.body(BodyInserters.fromObject(representation));
}
private ErrorRepresentation createErrorRepresentation(ServerRequest request) {
boolean includeStackTrace = isIncludeStackTrace(request, MediaType.ALL);
Map<String, Object> error = getErrorAttributes(request, includeStackTrace);
Throwable throwable = getError(request);
if (throwable instanceof AuthenticationException) {
AuthenticationFailureException failureException = new AuthenticationFailureException(throwable.getMessage());
return new ErrorRepresentation(failureException, error.get("path").toString());
}
}
}
推荐阅读
- javascript - Select Field OnChange, Make Show/Hide, Shows Initially but Once Gone, Cant ReShow
- android - 可折叠视图不适用于 viewpager
- python - 多处理队列 - 子进程有时会卡住并且不会收获
- java - 仅当一个字符在匹配中出现 n 次时如何匹配?
- sql - Hibernate xml映射 - 在不同的外键列上加入
- c# - WIX:可执行文件在子目录中找不到 dll
- ruby-on-rails - Rails 实时匹配两个用户的方法
- android - Flutter - 无法解析 json 数组
- webpack - 对不在 node_modules 中的文件使用 html-webpack-externals-plugin
- python - ValueError:无法从
我尝试了以下示例。这应该显示图像处理结果。
from scipy import ndimage as n