淺析SpringSecurity未授權或權限不足的處理:AuthenticationEntryPoint認證入口點及其實現類簡介及AccessDeineHandler介紹


一、AuthenticationEntryPoint簡介

  AuthenticationEntryPoint是Spring Security Web一個概念模型接口,顧名思義,他所建模的概念是:“認證入口點”。

  它在用戶請求處理過程中遇到認證異常時,被ExceptionTranslationFilter用於開啟特定認證方案(authentication schema)的認證流程

  該接口只定義了一個方法:

void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException;

  這里參數request是遇到了認證異常authException用戶請求,response是將要返回給客戶的相應,方法commence實現,也就是相應的認證方案邏輯會修改response並返回給用戶引導用戶進入認證流程。

  在該方法被調用前,ExceptionTranslationFilter會做好如下工作:填充屬性HttpSession,使用屬性名稱為AbstractAuthenticationProcessingFilter.SPRING_SECURITY_SAVED_REQUEST_KEY

二、AuthenticationEntryPoint源代碼

package org.springframework.security.web; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.access.ExceptionTranslationFilter; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public interface AuthenticationEntryPoint { /** * Commences an authentication scheme. * * ExceptionTranslationFilter will populate the HttpSession * attribute named * AbstractAuthenticationProcessingFilter.SPRING_SECURITY_SAVED_REQUEST_KEY * with the requested target URL before calling this method. * * Implementations should modify the headers on the ServletResponse as * necessary to commence the authentication process. * * @param request that resulted in an AuthenticationException * @param response so that the user agent can begin authentication * @param authException that caused the invocation * */
    void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException; }

  Spring Security Web 為AuthenticationEntryPoint提供了一些內置實現:

1、Http403ForbiddenEntryPoint:設置響應狀態字為403,並非觸發一個真正的認證流程。通常在一個預驗證(pre-authenticated authentication)已經得出結論需要拒絕用戶請求的情況被用於拒絕用戶請求。

2、HttpStatusEntryPoint:設置特定的響應狀態字,並非觸發一個真正的認證流程。

3、LoginUrlAuthenticationEntryPoint:根據配置計算出登錄頁面url,將用戶重定向到該登錄頁面從而開始一個認證流程。

4、BasicAuthenticationEntryPoint:對應標准Http Basic認證流程的觸發動作,向響應寫入狀態字401和頭部WWW-Authenticate:"Basic realm="xxx"觸發標准Http Basic認證流程。

5、DigestAuthenticationEntryPoint:對應標准Http Digest認證流程的觸發動作,向響應寫入狀態字401和頭部WWW-Authenticate:"Digest realm="xxx"觸發標准Http Digest認證流程。

6、DelegatingAuthenticationEntryPoint:這是一個代理,將認證任務委托給所代理的多個AuthenticationEntryPoint對象,其中一個被標記為缺省AuthenticationEntryPoint。

三、自定義認證返回

public class ExamAuthenticationEntryPoint implements AuthenticationEntryPoint { @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException { response.setStatus(HttpStatus.UNAUTHORIZED.value()); OperationInfo info = OperationInfo.failure("請登錄后操作"); HttpResponseUtil.setResponseMessage(response, info); } }

1、實現 AuthenticationEntryPoint  類,覆寫 commence 方法。

2、設置ExamAuthenticationEntryPoint

@Override protected void configure(HttpSecurity http) throws Exception { http.csrf()...... .exceptionHandling().authenticationEntryPoint(new ExamAuthenticationEntryPoint()) ...... }

四、自定義AccessDeineHandler

  AuthenticationEntryPoint 用來解決匿名用戶訪問無權限資源時的異常   ——  也就是未授權的問題

  AccessDeineHandler 用來解決認證過的用戶訪問無權限資源時的異常  ——  也就是權限不足的問題

public class CustomAccessDeineHandler implements AccessDeniedHandler { @Override public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException { response.setCharacterEncoding("utf-8"); response.setContentType("text/javascript;charset=utf-8"); response.getWriter().print(JSONObject.toJSONString(RestMsg.error("沒有訪問權限!"))); } }
//添加自定義異常入口,處理accessdeine異常
http.exceptionHandling().authenticationEntryPoint(new CustomAuthenticationEntryPoint()) .accessDeniedHandler(new CustomAccessDeineHandler());

// 禁用緩存 http.headers().cacheControl(); // 添加JWT filter http.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class); //添加未授權處理 http.exceptionHandling().authenticationEntryPoint(new CustomAuthenticationEntryPoint()); //權限不足處理 http.exceptionHandling().accessDeniedHandler(getAccessDeniedHandler());

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM