Spring Boot 攔截302,直接返回401

原文鏈接
問題:
在使用Spring security時(shí)使用postman訪問登錄失敗能得到自定義錯誤信息401,但是使用瀏覽器訪問的時(shí)候,當(dāng)?shù)卿洺晒r(shí)能正常進(jìn)入自定義配置類,但是失敗是直接給瀏覽器返回一個狀態(tài)碼302,并且通過查看斷點(diǎn)并不能進(jìn)入配置類

原因:
spring security對未認(rèn)證的訪問會默認(rèn)重定向一個接口,因前后端分離,所以不能實(shí)現(xiàn)前端自定義跳轉(zhuǎn)到登陸頁面的邏輯,實(shí)際修改方案就是后臺修改spring security框架默認(rèn)的302執(zhí)行邏輯。

解決方法:
實(shí)現(xiàn)AuthenticationEntryPoint接口,覆寫commence方法,修改返回狀態(tài)值為401,修改配置。讓前端去獲取狀態(tài)碼執(zhí)行前端的邏輯。

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

commence方法的具體實(shí)現(xiàn)做了些修改:
不是直接返回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());


補(bǔ)充

  • AuthenticationEntryPoint 用來解決匿名用戶訪問無權(quán)限資源時(shí)的異常
  • AccessDeineHandler 用來解決認(rèn)證過的用戶訪問無權(quán)限資源時(shí)的異常
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容