最近中文字幕高清中文字幕无,亚洲欧美高清一区二区三区,一本色道无码道dvd在线观看 ,一个人看的www免费高清中文字幕

首頁(yè) 慕課教程 Spring Security Spring Security Spring Security 異?;厥?/span>

1. 前言

上一節(jié)中我們介紹了 Spring Security 中內(nèi)置的安全過(guò)濾器,本節(jié)將介紹 Spring Security 的另一個(gè)基礎(chǔ)概念:「異常處理」。

這里所指異常是 Spring Security 在認(rèn)證和鑒權(quán)過(guò)程中捕獲的異常,也就是訪問(wèn)目標(biāo)資源發(fā)生錯(cuò)誤時(shí)的原因,Spring Security 以異常的形式處理「認(rèn)證錯(cuò)誤」和「權(quán)限錯(cuò)誤」,并將結(jié)果傳回請(qǐng)求方。

學(xué)習(xí) Spring Security 的異?;厥諜C(jī)制,有助于在開(kāi)發(fā)和應(yīng)用過(guò)程中排查問(wèn)題。

2. 異常處理流程

Spring Security 的認(rèn)證、授權(quán)異常在過(guò)濾器校驗(yàn)過(guò)程中產(chǎn)生,并在 ExceptionTranslationFilter 中接收并進(jìn)行處理,其流程如下:

圖片描述

圖1. ExceptionTranslationFilter
  1. ExceptionTranslationFilter 過(guò)濾器首先像其他過(guò)濾器一樣,調(diào)用過(guò)濾器鏈的執(zhí)行方法 FilterChain.doFilter(request, response) 啟動(dòng)過(guò)濾處理;
  2. 如果當(dāng)前的用戶沒(méi)有通過(guò)認(rèn)證或者因?yàn)槠渌蛟趫?zhí)行過(guò)程中拋出了 AuthenticationException 異常,此時(shí)將開(kāi)啟「認(rèn)證流程」:
    1. 清空 SecurityContextHolder 對(duì)象;
    2. 并將原始請(qǐng)求信息「request」保存到 RequestCache 對(duì)象中;
    3. 使用 AuthenticationEntryPoint 對(duì)象存儲(chǔ)的認(rèn)證地址,向客戶端索要身份證明。例如,使用瀏覽器登錄的用戶,將瀏覽器地址重定向到 /login 或者回傳一個(gè) WWW-Authenticate 認(rèn)證請(qǐng)求頭。
  3. 如果當(dāng)前用戶身份信息已確認(rèn),但是沒(méi)有訪問(wèn)權(quán)限,則會(huì)產(chǎn)生 AccessDeniedException 異常,然后訪問(wèn)被拒絕。繼續(xù)執(zhí)行拒絕處理 AccessDeniedHandler。

假如認(rèn)證過(guò)程中沒(méi)有產(chǎn)生「認(rèn)證異?!够蛘摺笝?quán)限異?!?,ExceptionTranslationFilter 則不做任何處理。

3. 異常的種類

圖片描述

圖2. 主要的異常種類

3.1 認(rèn)證異常

認(rèn)證異常是在認(rèn)證階段拋出的異常,其主要的實(shí)現(xiàn)類包括:

  • AccountStatusException

    出現(xiàn)在賬戶狀態(tài)異常時(shí)候,比如認(rèn)證憑據(jù)過(guò)期了、賬戶被鎖定了等。

  • ActiveDirectoryAuthenticationException

    出現(xiàn)在 AD 域認(rèn)證異常時(shí)。

  • AuthenticationCancelledException

    出現(xiàn)在 OpenID 認(rèn)證時(shí),認(rèn)證狀態(tài)被取消。

  • AuthenticationCredentialsNotFoundException

    出現(xiàn)在無(wú)法找到認(rèn)證憑證時(shí),即 SecurityContext 實(shí)例中找不到 Authentication 對(duì)象。

  • AuthenticationServiceException

    出現(xiàn)在認(rèn)證時(shí)遇到了后臺(tái)錯(cuò)誤。

  • BadCredentialsException

    出現(xiàn)在憑據(jù)檢查失敗,比如賬戶被禁用時(shí)。

  • InsufficientAuthenticationException

    出現(xiàn)在以獲得憑據(jù),但憑據(jù)不被信任的情況。

  • NonceExpiredException

    出現(xiàn)在數(shù)字證書(shū)異常時(shí)。

  • OAuth2AuthenticationException

    出現(xiàn)在 OAuth2 認(rèn)證異常時(shí)。

  • PreAuthenticatedCredentialsNotFoundException

    出現(xiàn)在預(yù)認(rèn)證憑據(jù)未找到時(shí)。

  • ProviderNotFoundException

    出現(xiàn)在當(dāng)前認(rèn)證方式不被支持時(shí)。

  • RememberMeAuthenticationException

    出現(xiàn)在記住我認(rèn)證失敗時(shí)。

  • Saml2AuthenticationException

    出現(xiàn)在 Saml2 認(rèn)證失敗時(shí)。

  • SessionAuthenticationException

    出現(xiàn)在會(huì)話異常時(shí),比如當(dāng)前用戶創(chuàng)建的會(huì)話已經(jīng)超過(guò)系統(tǒng)容量。

  • UsernameNotFoundException

    出現(xiàn)在找不到用戶時(shí)。

3.2 權(quán)限異常

權(quán)限異常是在訪問(wèn)資源階段拋出的異常,其主要的實(shí)現(xiàn)類包括:

  • AuthorizationServiceException

    當(dāng)鑒權(quán)請(qǐng)求無(wú)法完成或者,比如找不到目標(biāo)方法時(shí)拋出此異常。

  • org.springframework.security.web.server.csrf.CsrfException

    當(dāng) 「CsrfToken」異?;蛉笔r(shí)拋出此異常。

  • org.springframework.security.web.csrf.CsrfException

    當(dāng) 「CsrfToken」異?;蛉笔r(shí)拋出此異常。

4. 自定義異常處理

當(dāng)我們需要自定義異常處理時(shí),需要在 HttpSecurity 對(duì)象的 exceptionHandling() 方法獲取異常處理的配置入口 ExceptionHandlingConfigurer,并使用該類提供的 AuthenticationEntryPointAccessDeniedHandler 參數(shù)來(lái)配置異常處理:

  • AuthenticationEntryPoint 該類用來(lái)統(tǒng)一處理 AuthenticationException 異常;
  • AccessDeniedHandler 該類用來(lái)統(tǒng)一處理 AccessDeniedException 異常。

4.1 自定義 AuthenticationEntryPoint

假設(shè)我們想統(tǒng)一異常 json 響應(yīng)。

public class JSONAuthenticationEntryPoint implements AuthenticationEntryPoint {
  @Override
  public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
    // 實(shí)現(xiàn)個(gè)性化業(yè)務(wù)邏輯 ...
    
    // 配置返回值
    HashMap<String, String> map = new HashMap<>(2);
    map.put("uri", request.getRequestURI());
    map.put("msg", "認(rèn)證失敗");
    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 實(shí)現(xiàn) AccessDeniedHandler

同樣假設(shè)我們想統(tǒng)一異常 json 響應(yīng)。

public class JSONAccessDeniedHandler implements AccessDeniedHandler {
  @Override
  public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
    // 實(shí)現(xiàn)個(gè)性化業(yè)務(wù)邏輯 ...
    
    // 配置返回值
    HashMap<String, String> map = new HashMap<>(2);
    map.put("uri", request.getRequestURI());
    map.put("msg", "認(rèn)證失敗");
    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();
  }
}

5. 小結(jié)

本節(jié)我們介紹了 Spring Security 中的異?;厥諜C(jī)制:

  • Spring Security 的異常處理是通過(guò)「安全過(guò)濾器」方式實(shí)現(xiàn)的;
  • Spring Security 的異常分為兩大類,分別是「身份異?!购汀笝?quán)限異?!?;
  • Spring Security 可以通過(guò)修改配置自定義異常處理。

至此,關(guān)于 Spring Security 基礎(chǔ)部分就告一段了,下節(jié)開(kāi)始我們進(jìn)入應(yīng)用環(huán)節(jié),討論 Spring Security 的第一個(gè)重要模塊「認(rèn)證」。