为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

智慧大石 2023-07-19 16:26:29
我必须在 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 默认页面。
查看完整描述

2 回答

?
慕田峪4524236

TA贡献1875条经验 获得超5个赞

最后我找到了解决我的问题的方法。我重写 RequestBodyReaderAuthenticationFilter 类的 unsuccessfulAuthentication 方法,并重定向到我的登录错误页面。

我做了很多证明,并且在所有情况下都是成功的。

现在的班级是:

   @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);

        }


        @Override

        protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {

            LOG.error("El usuario no existe en AD");

            response.sendRedirect(request.getContextPath()+"/login?error"); //To change body of generated methods, choose Tools | Templates.

        }


        @Override

        public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {

            String requestBody;

            Boolean valido = false;

            try {

                requestBody = IOUtils.toString(request.getReader());

                ArrayList<String> credenciales = new ArrayList<String>();

                //Busco el Usu y pass enviados en el request

                for (String val : requestBody.split("&")) {

                    credenciales.add(val.split("=")[1]);

                }


                try {

                    //hago el llamado el WS

                    org.tempuri.ADWS service = new org.tempuri.ADWS();

                    org.tempuri.IADWS port = service.getBasicHttpBindingIADWS();


                    valido = port.login(credenciales.get(0), credenciales.get(1));

                } catch (Exception ex) {

                    LOG.error(ERROR_MESSAGE, ex);

                }

                UsernamePasswordAuthenticationToken token;

                if (valido) {

                    //si existe en AD, realizo la validación en el sistema

                    token = new UsernamePasswordAuthenticationToken(credenciales.get(0), credenciales.get(1));

                    setDetails(request, token);

                    return this.getAuthenticationManager().authenticate(token);

                }else{

                    throw new InternalAuthenticationServiceException(ERROR_MESSAGE);                

                }

            } catch (IOException e) {

                LOG.error(ERROR_MESSAGE, e);

                throw new InternalAuthenticationServiceException(ERROR_MESSAGE, e);

            }

        }

    }


查看完整回答
反对 回复 2023-07-19
?
慕姐4208626

TA贡献1852条经验 获得超7个赞

如果我理解正确,用户可以登录,但是在过滤器中,您正在检查一些额外的验证,因为用户未获得授权?然后你必须设置

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

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


查看完整回答
反对 回复 2023-07-19
  • 2 回答
  • 0 关注
  • 166 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信