Webflux 安全登录失败处理程序不起作用
Posted
技术标签:
【中文标题】Webflux 安全登录失败处理程序不起作用【英文标题】:Webflux security login failure handler does not work 【发布时间】:2019-08-27 04:42:59 【问题描述】:如果登录/注销成功或失败,我正在尝试使用 Spring webflux 安全自定义字符串消息进行设置。除“authenticationFailureHandler”外,处理程序正在工作。
文档中提到了一些关于“logoutSuccessUrl()”的内容,但它不存在,并且这些处理程序返回 Mono。
所以我有两个问题:
我如何返回一些字符串作为响应,例如,如果身份验证失败,则类似于“无效的用户名或密码”或一些 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();
【问题讨论】:
我做了一个功能齐全的示例项目,实现了 webflux + webflux-security,它包含了关于成功 + 失败处理程序的完整工作流程,你可以在这里看到:github.com/eriknyk/webflux-jwt-security-demo 【参考方案1】:我遇到了同样的问题,最终使用自定义 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());
【讨论】:
【参考方案2】:对于响应,我必须使用“RedirectServerAuthenticationSuccessHandler”来获得身份验证成功。我创建了完全相同的类来实现失败。
身份验证失败处理程序不起作用是一个已知问题。为了使其工作,您必须设置登录页面。所以我只是将其更新为默认的“/ login”
【讨论】:
此问题仍未解决。但是您的登录页面技巧有效:) 谢谢以上是关于Webflux 安全登录失败处理程序不起作用的主要内容,如果未能解决你的问题,请参考以下文章