美文网首页
Spring Boot 拦截302,直接返回401

Spring Boot 拦截302,直接返回401

作者: 邮差在行动 | 来源:发表于2020-07-03 16:00 被阅读0次

    原文链接
    问题:
    在使用Spring security时使用postman访问登录失败能得到自定义错误信息401,但是使用浏览器访问的时候,当登录成功时能正常进入自定义配置类,但是失败是直接给浏览器返回一个状态码302,并且通过查看断点并不能进入配置类

    原因:
    spring security对未认证的访问会默认重定向一个接口,因前后端分离,所以不能实现前端自定义跳转到登陆页面的逻辑,实际修改方案就是后台修改spring security框架默认的302执行逻辑。

    解决方法:
    实现AuthenticationEntryPoint接口,覆写commence方法,修改返回状态值为401,修改配置。让前端去获取状态码执行前端的逻辑。

    public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
        @Override
        public void commence(HttpServletRequest request, HttpServletResponse response,
                             AuthenticationException authException) throws IOException, ServletException {
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
        }
    }
    

    commence方法的具体实现做了些修改:
    不是直接返回401,加一些判断再返回401

    if (request.getHeader("x-requested-with") != null && request.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")){
                 Cookie[] cookies = request.getCookies();
                 if (cookies == null) { // JSESSIONID不存在了,删除了
                     response.setStatus(HttpStatus.UNAUTHORIZED.value());
                 } else {
                     boolean hasJSessionid = false;
                     for(Cookie c : cookies) {
                         if (c.getName().equals("JSESSIONID")) {
                             hasJSessionid = true;
                             break;
                         }
                     }
                     if (!hasJSessionid) { // JSESSIONID不存在了,修改了
                         response.setStatus(HttpStatus.UNAUTHORIZED.value());
                     } else { // JSESSIONID存在,判断是否合法
                         HttpSession session = request.getSession(true);
                         if(session.isNew()) {
                             response.setStatus(HttpStatus.UNAUTHORIZED.value());
                         }
                     }
                 }
             }  
    
    @Configuration
    public class BrowserSecurityConfig extends AbstractChannelSecurityConfig {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            applyPasswordAuthenticationConfig(http);
            http.apply(validateCodeSecurityConfig)
            .and()
            .apply(smsCodeAuthenticationSecurityConfig)
            .and()
            .apply(imoocSocialSecurityConfig)
            .and()
            .sessionManagement()
            .invalidSessionStrategy(invalidSessionStrategy)
            .maximumSessions(securityProperties.getBrowser().getSession().getMaximumSessions())
            .maxSessionsPreventsLogin(securityProperties.getBrowser().getSession()
            .isMaxSessionsPreventsLogin())
            .expiredSessionStrategy(sessionInformationExpiredStrategy)
            .and()
            .and()
            .logout()
            .logoutSuccessHandler(onstepLogoutSuccessHandler)
            .deleteCookies("JSESSIONID")
            .and()
            .authorizeRequests()
            .antMatchers(
            securityProperties.getBrowser().getLoginPage(),
            securityProperties.getBrowser().getSignUpUrl())
            .permitAll()
            .anyRequest()
            .authenticated()
            .and()
            .cors()
            .and()
            .csrf().disable()
            .exceptionHandling().authenticationEntryPoint(new CustomAuthenticationEntryPoint());
        }
    }
    

    主要注意的代码:

    1.response.setStatus(HttpStatus.UNAUTHORIZED.value());
    2..exceptionHandling().authenticationEntryPoint(new CustomAuthenticationEntryPoint());


    补充

    • AuthenticationEntryPoint 用来解决匿名用户访问无权限资源时的异常
    • AccessDeineHandler 用来解决认证过的用户访问无权限资源时的异常

    相关文章

      网友评论

          本文标题:Spring Boot 拦截302,直接返回401

          本文链接:https://www.haomeiwen.com/subject/fxisqktx.html