JAVA - 自定义过滤器验证失败后如何重定向到登录页面?

我必须在 Spring-security 中的验证过程中添加一些额外的验证。我在配置 xml 中添加了“自定义过滤器”,但是当它失败时,会将我重定向到错误页面,而不是登录页面。我可以毫无问题地访问我的“authenticationFilter”类,并且当我的凭据良好并进入主页面时,我不会遇到问题。


我的 Spring 安全配置是:


<http auto-config="true" use-expressions="true">

    <intercept-url pattern="/admin**" access="hasRole('ADMIN')" />

    <intercept-url pattern="/login" access="permitAll" />

    <intercept-url pattern="/**" access="isAuthenticated()" />


    <custom-filter 

        ref="authenticationFilter" 

            before="FORM_LOGIN_FILTER"

    />

    <!-- access denied page -->

    <access-denied-handler error-page="/403" />

    <form-login 

        login-page="/login" 

        default-target-url="/home"

        authentication-failure-url="/login?error" 

        username-parameter="username"

        password-parameter="password"

    />

    <logout logout-success-url="/login?logout" />

</http>

我的过滤器是:


@Component("authenticationFilter")

public class RequestBodyReaderAuthenticationFilter extends UsernamePasswordAuthenticationFilter {


    private static final Log LOG = LogFactory.getLog(RequestBodyReaderAuthenticationFilter.class);


    private static final String ERROR_MESSAGE = "Error en la validación con AD";


    private final ObjectMapper objectMapper = new ObjectMapper();


    public RequestBodyReaderAuthenticationFilter() {

    }


    @Autowired

    @Qualifier("authenticationManager")

    @Override

    public void setAuthenticationManager(AuthenticationManager authenticationManager) {

        super.setAuthenticationManager(authenticationManager);

    }



我需要当“自定义过滤器”验证失败时,它重定向到登录页面,而不是抛出 401/403 默认页面。


智慧大石
浏览 167回答 2
2回答

慕田峪4524236

最后我找到了解决我的问题的方法。我重写 RequestBodyReaderAuthenticationFilter 类的 unsuccessfulAuthentication 方法,并重定向到我的登录错误页面。我做了很多证明,并且在所有情况下都是成功的。现在的班级是:&nbsp; &nbsp;@Component("authenticationFilter")&nbsp; &nbsp; public class RequestBodyReaderAuthenticationFilter extends UsernamePasswordAuthenticationFilter {&nbsp; &nbsp; &nbsp; &nbsp; private static final Log LOG = LogFactory.getLog(RequestBodyReaderAuthenticationFilter.class);&nbsp; &nbsp; &nbsp; &nbsp; private static final String ERROR_MESSAGE = "Error en la validación con AD";&nbsp; &nbsp; &nbsp; &nbsp; private final ObjectMapper objectMapper = new ObjectMapper();&nbsp; &nbsp; &nbsp; &nbsp; public RequestBodyReaderAuthenticationFilter() {&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; @Autowired&nbsp; &nbsp; &nbsp; &nbsp; @Qualifier("authenticationManager")&nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; public void setAuthenticationManager(AuthenticationManager authenticationManager) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; super.setAuthenticationManager(authenticationManager);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LOG.error("El usuario no existe en AD");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; response.sendRedirect(request.getContextPath()+"/login?error"); //To change body of generated methods, choose Tools | Templates.&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String requestBody;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Boolean valido = false;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; requestBody = IOUtils.toString(request.getReader());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ArrayList<String> credenciales = new ArrayList<String>();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //Busco el Usu y pass enviados en el request&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (String val : requestBody.split("&")) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; credenciales.add(val.split("=")[1]);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //hago el llamado el WS&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; org.tempuri.ADWS service = new org.tempuri.ADWS();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; org.tempuri.IADWS port = service.getBasicHttpBindingIADWS();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; valido = port.login(credenciales.get(0), credenciales.get(1));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } catch (Exception ex) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LOG.error(ERROR_MESSAGE, ex);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UsernamePasswordAuthenticationToken token;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (valido) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //si existe en AD, realizo la validación en el sistema&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; token = new UsernamePasswordAuthenticationToken(credenciales.get(0), credenciales.get(1));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setDetails(request, token);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return this.getAuthenticationManager().authenticate(token);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }else{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new InternalAuthenticationServiceException(ERROR_MESSAGE);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } catch (IOException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LOG.error(ERROR_MESSAGE, e);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new InternalAuthenticationServiceException(ERROR_MESSAGE, e);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }

慕姐4208626

如果我理解正确,用户可以登录,但是在过滤器中,您正在检查一些额外的验证,因为用户未获得授权?然后你必须设置<access-denied-handler&nbsp;error-page="/403"&nbsp;/>到<access-denied-handler&nbsp;error-page="/login"&nbsp;/>
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java