SpringBoot 2整合SpringSecurity權限管理(二)配置自定義登錄成功和失敗處理器

概述

上一篇文章講了,登陸完後會給我們返回信息,這沒毛病,但是問題來了,他跳轉了頁面,假設我們不想跳轉頁面,只想返回固定格式的JSON呢?這就需要我們自定義成功處理器了。失敗的情況也雷同。

一、創建登錄成功處理器LoginSuccessHandler,並重寫onAuthenticationSuccess方法

@Slf4j
@Component
public class LoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws ServletException, IOException {
        log.info("登錄成功!");
        /* 默認:會幫我們跳轉到上一次請求的頁面上 */
        //super.onAuthenticationSuccess(request, response, authentication);
        response.setStatus(HttpServletResponse.SC_OK);
        response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
        PrintWriter writer = response.getWriter();
        writer.write("登錄成功");
        writer.flush();
        writer.close();
    }
}

Spring Security完成用戶登錄後跳轉回原頁面的處理是在SavedRequestAwareAuthenticationSuccessHandler類裏面進行的,如果想要自定義登錄成功後的操作可以繼承該類,重寫該方法。爲什麼不實現AuthenticationSuccessHandler接口,而是繼承SavedRequestAwareAuthenticationSuccessHandler類的方式?因爲SavedRequestAwareAuthenticationSuccessHandler這個類記住了你上一次的請求路徑,比如:你請求user.html。然後被攔截到了登錄頁,這時候你輸入完用戶名密碼點擊登錄,會自動跳轉到user.html,而不是主頁面。

若是前後分離項目則實現接口即可,因爲我弄的是通用的權限組件,所以選擇了繼承。

一種成功的身份驗證策略,通過ExceptionTranslationFilter,默認將DefaultSavedRequest存儲在session中當這樣的請求被截獲並需要身份驗證時,在身份驗證過程開始之前存儲請求數據以記錄原始目的地(url)並允許在重定向到相同的URL時重鍵請求,如果合適的話,這個類負責執行到原始URL的重定向。

在成功進行驗證之後,它根據以下場景確定重定向目標:

  1. 如果alwaysUseDefaultTargetUrl屬性設置爲true,則defaultTargetUrl將用於目標.會話中存儲的任何defaultSavedRequest將被刪除。
  2. 如果在請求中設置了targetUrlParameter,則該值將用作目標。defaultTargetUrl將再次被刪除
  3. 如果在RequestCache中找到SavedRequest(由ExceptionTranslationFilter所設置,在驗證過程開始之前記錄原始目的地),將對原始目的地的Url執行重定向。當收到重定向請求時,SavedRequest對象將保持緩存狀態並被拾取(請參閱SavedRequestAwareWrapper)
  4. 如果找不到SavedRequest它將委託給基類(父類)。

二、創建登錄失敗處理器,並重寫onAuthenticationFailure方法

@Slf4j
@Component
public class LoginFailureHandler extends SimpleUrlAuthenticationFailureHandler {

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
        /* 默認:執行重定向或轉發到defaultfailureurl(如果設置),Otherw返回401錯誤代碼 */
        //super.onAuthenticationFailure(request,response,exception)
        log.error("登錄錯誤 [{}] ",exception.getMessage());
        response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
        response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
        PrintWriter writer = response.getWriter();
        writer.write(exception.getMessage());
        writer.flush();
        writer.close();
    }
}

AuthenticationFailureHandler接口定義了Spring Security Web在遇到認證錯誤時所使用的處理策略。

典型做法一般是將用戶重定向到認證頁面(比如認證機制是用戶名錶單認證的情況)讓用戶再次認證。當然具體實現類可以根據需求實現更復雜的邏輯,比如根據異常做不同的處理等等。舉個例子,如果遇到CredentialsExpiredException異常(AuthenticationException異常的一種,表示密碼過期失效),可以將用戶重定向到修改密碼頁面而不是登錄認證頁面。

在Spring Security Web框架內部,缺省使用的認證錯誤處理策略是AuthenticationFailureHandler的實現類SimpleUrlAuthenticationFailureHandler。它由配置指定一個defaultFailureUrl,表示認證失敗時缺省使用的重定向地址。一旦認證失敗,它的方法onAuthenticationFailure被調用時,它就會將用戶重定向到該地址。如果該屬性沒有設置,它會向客戶端返回一個401狀態碼。另外SimpleUrlAuthenticationFailureHandler還有一個屬性useForward,如果該屬性設置爲true,頁面跳轉將不再是重定向(redirect)機制,取而代之的是轉發(forward)機制。

三、把自定義處理器加入security認證中

在SecurityConfig配置類的configure(HttpSecurity http)方法中加入我們自定義的處理Handler

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests() //需要授權的請求
        .antMatchers("/login","/home").permitAll() //過濾不需要認證的路徑
        .anyRequest().authenticated() //對任何一個請求,都需要認證
        .and() //完成上一個配置,進行下一步配置
        //.httpBasic();
        .formLogin() //配置表單登錄
        .loginPage("/login") //設置登錄頁面
        .successHandler(successHandler)  /* 設置成功處理器 */
        .failureHandler(failureHandler)  /* 設置失敗處理器*/
        .and()
        .logout() //登出
        .logoutSuccessUrl("/home"); //設置退出頁面
}

四、啓動項目測試

66666666

7777778

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章