首页 > 解决方案 > Webflux 安全登录失败处理程序不起作用

问题描述

如果登录/注销成功或失败,我正在尝试使用 Spring webflux 安全自定义字符串消息进行设置。除“authenticationFailureHandler”外,处理程序正在工作。

文档中提到了一些关于“logoutSuccessUrl()”的内容,但它不存在,并且这些处理程序返回 Mono< Void >。

所以我有两个问题:

-我尝试使用 Mono.just("redirect:/some-url").then() 进行重定向,但它没有做任何事情。对于回复

你可以在这里找到我的全部代码: 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();
    }
}

标签: javaspringsecurityspring-webfluxreactive

解决方案


我遇到了同样的问题,最终使用自定义 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());
        }

    }
}

推荐阅读