Spring Security 实战干货:自定义异常处理
Spring Security 實戰干貨:自定義異常處理
轉自:https://www.cnblogs.com/felordcn/p/12142514.html
文章目錄
-
- 1. 前言
- 2. Spring Security 中的異常
- 2.1 AuthenticationException
- 2.2 AccessDeniedException
- 3. Http 狀態對認證授權的規定
- 3.1 401 未授權狀態
- 3.2 403 被拒絕狀態
- 4. Spring Security 中的異常處理
- 4.1 實現 AuthenticationEntryPoint
- 4.2 實現 AccessDeniedHandler
- 4.3 個人實踐建議
- 4.4 配置
- 5. 總結
?
1. 前言
最近實在比較忙,很難抽出時間來繼續更?Spring Security 實戰干貨系列。今天正好項目中?Spring Security?需要對認證授權異常的處理,就分享出來吧 。
2. Spring Security 中的異常
Spring Security?中的異常主要分為兩大類:一類是認證異常,另一類是授權相關的異常。
2.1 AuthenticationException
AuthenticationException?是在用戶認證的時候出現錯誤時拋出的異常。主要的子類如圖:
根據該圖的信息,系統用戶不存在,被鎖定,憑證失效,密碼錯誤等認證過程中出現的異常都由?AuthenticationException?處理。
2.2 AccessDeniedException
AccessDeniedException?主要是在用戶在訪問受保護資源時被拒絕而拋出的異常。同?AuthenticationException?一樣它也提供了一些具體的子類。如下圖:
AccessDeniedException?的子類比較少,主要是?CSRF?相關的異常和授權服務異常。
3. Http 狀態對認證授權的規定
Http?協議對認證授權的響應結果也有規定。
3.1 401 未授權狀態
HTTP 401 錯誤 - 未授權(Unauthorized)?一般來說該錯誤消息表明您首先需要登錄(輸入有效的用戶名和密碼)。 如果你剛剛輸入這些信息,立刻就看到一個?401?錯誤,就意味著,無論出于何種原因您的用戶名和密碼其中之一或兩者都無效(輸入有誤,用戶名暫時停用,賬戶被鎖定,憑證失效等) 。總之就是認證失敗了。其實正好對應我們上面的?AuthenticationException?。
3.2 403 被拒絕狀態
HTTP 403 錯誤 - 被禁止(Forbidden)?出現該錯誤表明您在訪問受限資源時沒有得到許可。服務器理解了本次請求但是拒絕執行該任務,該請求不該重發給服務器。并且服務器想讓客戶端知道為什么沒有權限訪問特定的資源,服務器應該在返回的信息中描述拒絕的理由。一般實踐中我們會比較模糊的表明原因。 該錯誤對應了我們上面的?AccessDeniedException?。
4. Spring Security 中的異常處理
我們在?Spring Security?實戰干貨系列文章中的?自定義配置類入口 WebSecurityConfigurerAdapter?一文中提到?HttpSecurity?提供的?exceptionHandling()?方法用來提供異常處理。該方法構造出?ExceptionHandlingConfigurer?異常處理配置類。該配置類提供了兩個實用接口:
- AuthenticationEntryPoint?該類用來統一處理?
AuthenticationException?異常 - AccessDeniedHandler?該類用來統一處理?
AccessDeniedException?異常
我們只要實現并配置這兩個異常處理類即可實現對?Spring Security?認證授權相關的異常進行統一的自定義處理。
4.1 實現 AuthenticationEntryPoint
以?json?信息響應。
import com.fasterxml.jackson.databind.ObjectMapper;import org.springframework.http.MediaType;import org.springframework.security.core.AuthenticationException;import org.springframework.security.web.AuthenticationEntryPoint;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.PrintWriter;import java.util.HashMap;/*** @author dax* @since 2019/11/6 22:11*/public class SimpleAuthenticationEntryPoint implements AuthenticationEntryPoint {@Overridepublic void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {//todo your businessHashMap<String, String> map = new HashMap<>(2);map.put("uri", request.getRequestURI());map.put("msg", "認證失敗");response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);response.setCharacterEncoding("utf-8");response.setContentType(MediaType.APPLICATION_JSON_VALUE);ObjectMapper objectMapper = new ObjectMapper();String resBody = objectMapper.writeValueAsString(map);PrintWriter printWriter = response.getWriter();printWriter.print(resBody);printWriter.flush();printWriter.close();}}
4.2 實現 AccessDeniedHandler
同樣以?json?信息響應。
import com.fasterxml.jackson.databind.ObjectMapper;import org.springframework.http.MediaType;import org.springframework.security.access.AccessDeniedException;import org.springframework.security.web.access.AccessDeniedHandler;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.PrintWriter;import java.util.HashMap;/*** @author dax* @since 2019/11/6 22:19*/public class SimpleAccessDeniedHandler implements AccessDeniedHandler {@Overridepublic void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {//todo your businessHashMap<String, String> map = new HashMap<>(2);map.put("uri", request.getRequestURI());map.put("msg", "認證失敗");response.setStatus(HttpServletResponse.SC_FORBIDDEN);response.setCharacterEncoding("utf-8");response.setContentType(MediaType.APPLICATION_JSON_VALUE);ObjectMapper objectMapper = new ObjectMapper();String resBody = objectMapper.writeValueAsString(map);PrintWriter printWriter = response.getWriter();printWriter.print(resBody);printWriter.flush();printWriter.close();}}
4.3 個人實踐建議
其實我個人建議?Http?狀態碼 都返回?200?而將 401 狀態在 元信息?Map?中返回。因為異常狀態碼在瀏覽器端會以?error?顯示。我們只要能捕捉到?401?和?403?就能認定是認證問題還是授權問題。
4.4 配置
實現了上述兩個接口后,我們只需要在?WebSecurityConfigurerAdapter?的?configure(HttpSecurity http)?方法中配置即可。相關的配置片段如下:
http.exceptionHandling().accessDeniedHandler(new SimpleAccessDeniedHandler()).authenticationEntryPoint(new SimpleAuthenticationEntryPoint())
5. 總結
今天我們對?Spring Security?中的異常處理進行了講解。分別實現了自定義的認證異常處理和自定義的授權異常處理。相關的?DEMO?可關注微信公眾號:?Felordcn?回復?ss07?獲取。
關注公眾號:Felordcn獲取更多資訊
總結
以上是生活随笔為你收集整理的Spring Security 实战干货:自定义异常处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 别克英朗车头侧面补漆多少钱?
- 下一篇: 各种花包装花束需要多少支