Spring Security 實戰乾貨:SecurityContext相關的知識

1. 前言

歡迎閱讀 Spring Security 實戰乾貨 系列文章 。在前兩篇咱們講解了 基於配置基於註解 來配置訪問控制。今天咱們來說一下如何在接口訪問中檢索當前認證用戶信息。 咱們先講一下具體的場景。一般咱們在認證後訪問須要認證的資源時須要獲取當前認證用戶的信息。好比 「查詢個人我的信息」。若是你直接在接口訪問時顯式的傳入你的 UserID 確定是不合適的。由於你認證經過後訪問資源,系統是知道你是誰的。並且顯式的暴露用戶的檢索接口也不安全。因此咱們須要一個業務中能夠檢索當前認證用戶的工具。 接下來咱們來看看 Spring Security 是如何解決這個痛點的。html

2. 安全上下文 SecurityContext

不知道你有沒有留意Spring Security 實戰乾貨:使用 JWT 認證訪問接口 中是如何實現 JWT 認證攔截器 JwtAuthenticationFilter 。當服務端對 JWT Token 認證經過後,會將認證用戶的信息封裝到 UsernamePasswordAuthenticationToken 中 並使用工具類放入安全上下文 SecurityContext 中,當服務端響應用戶後又使用同一個工具類將 UsernamePasswordAuthenticationTokenSecurityContextclear 掉。 咱們來簡單瞭解 SecurityContext 具體是個什麼東西。java

package org.springframework.security.core.context;
 
 import java.io.Serializable;
 import org.springframework.security.core.Authentication;
 
 public interface SecurityContext extends Serializable {
     Authentication getAuthentication();
 
     void setAuthentication(Authentication var1);
 }
複製代碼

從源碼上來看很簡單就是一個 存儲 Authentication 的容器。而 Authentication 是一個用戶憑證接口用來做爲用戶認證的憑證使用,一般經常使用的實現有 認證用戶 UsernamePasswordAuthenticationToken匿名用戶AnonymousAuthenticationToken。其中 UsernamePasswordAuthenticationToken 包含了 UserDetails , AnonymousAuthenticationToken 只包含了一個字符串 anonymousUser 做爲匿名用戶的標識。咱們經過 SecurityContext 獲取上下文時須要來進行類型判斷。接下來咱們來聊聊操做 SecurityContext 的工具類。spring

3. SecurityContextHolder

這個工具類就是 SecurityContextHolder 。 它提供了兩個有用的方法:安全

  • clearContext 清除當前的 SecurityContext
  • getContext 獲取當前的 SecurityContext
  • setContext 設置當前的 SecurityContext

日常咱們經過這三個方法來操做安全上下文 SecurityContext 。你能夠直接在代碼中使用工具類 SecurityContextHolder 獲取用戶信息,像下面同樣:多線程

public String getCurrentUser() {
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
          
     if (authentication instanceof AnonymousAuthenticationToken){
         return "anonymousUser";
     }
    UserDetails principal = (UserDetails) authentication.getPrincipal();
    return principal.getUsername();
 }     
複製代碼

3.1 擴展知識:SecurityContextHolder的存儲策略

這裏也擴展一下知識面,簡單講一下 SecurityContextHolder 是如何存儲 SecurityContext 的。SecurityContextHolder 默認有三種存儲 SecurityContext 的策略:工具

  • MODE_THREADLOCAL 利用ThreadLocal 機制來保存每一個使用者的 SecurityContext缺省策略,日常咱們使用這個就好了。
  • MODE_INHERITABLETHREADLOCAL 利用InheritableThreadLocal 機制來保存每一個使用者的 SecurityContext,多用於多線程環境環境下。
  • MODE_GLOBAL 靜態機制,做用於全局。不太經常使用。

4. 總結

SecurityContextSpring Security 中的一個很是重要類,今天不但介紹 SecurityContext 是什麼、有什麼做用,也對之前講過的一些知識進行回顧。 也對如何使用 SecurityContextHolder 操做 SecurityContext 進行了講解。最後也簡單講述了 SecurityContextHolder 三種存儲 SecurityContext 的策略和使用場景 。但願對你學習 Spring Security 有幫助。還請多多關注。學習

關注公衆號:Felordcn獲取更多資訊spa

我的博客:https://felord.cn線程

相關文章
相關標籤/搜索