最基本的對象是`SecurityContextHolder`。 這是我們存儲應用程序當前安全上下文的詳細信息的地方,其中包括當前使用該應用程序的主體的詳細信息。 默認情況下,`SecurityContextHolder`使用`ThreadLocal`來存儲這些詳細信息,這意味著安全上下文始終可用于同一執行線程中的方法,即使安全上下文未作為這些方法的參數顯式傳遞。 如果在處理當前主體的請求之后注意清除線程,以這種方式使用ThreadLocal是非常安全的。 當然,Spring Security會自動為您解決這個問題,因此無需擔心。
某些應用程序并不完全適合使用`ThreadLocal`,因為它們使用線程的特定方式。 例如,Swing客戶端可能希望Java虛擬機中的所有線程都使用相同的安全上下文。 `SecurityContextHolder`可以在啟動時配置策略,以指定您希望如何存儲上下文。 對于獨立應用程序,您將使用`SecurityContextHolder.MODE_GLOBAL`策略。 其他應用程序可能希望安全線程生成的線程也采用相同的安全標識。 這是通過使用`SecurityContextHolder.MODE_INHERITABLETHREADLOCAL`實現的。 您可以通過兩種方式從默認的`SecurityContextHolder.MODE_THREADLOCAL`更改模式。 第一個是設置系統屬性,第二個是在`SecurityContextHolder`上調用靜態方法。 大多數應用程序不需要更改默認值,但如果這樣做,請查看JavaDoc for `SecurityContextHolder`以了解更多信息。
## 獲取有關當前用戶的信息
在`SecurityContextHolder`中,我們存儲當前與應用程序交互的主體的詳細信息。 Spring Security使用`Authentication`對象來表示此信息。 您通常不需要自己創建`Authentication`對象,但用戶查詢`Authentication`對象是相當常見的。 您可以使用以下代碼塊(從應用程序的任何位置)獲取當前經過身份驗證的用戶的名稱,例如:
~~~
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (principal instanceof UserDetails) {
String username = ((UserDetails)principal).getUsername();
} else {
String username = principal.toString();
}
~~~
調用`getContext()`返回的對象是`SecurityContext`接口的一個實例。 這是保存在線程本地存儲中的對象。 正如我們將在下面看到的,Spring Security中的大多數身份驗證機制都會返回`UserDetails`的實例作為主體。
- 架構
- 9.技術概述
- 9.1 運行環境
- 9.2 核心組件
- 9.2.1 SecurityContextHolder, SecurityContext and Authentication Objects
- 9.2.2 The UserDetailsService
- 9.2.3 GrantedAuthority
- 9.2.4 總結
- 9.3 驗證
- 9.3.1 在Spring Security中驗證是什么
- 9.3.2 直接設置SecurityContextHolder內容
- 9.4 web應用中的驗證
- 9.4.1 ExceptionTranslationFilter
- 9.4.2 AuthenticationEntryPoint
- 9.4.3 驗證機制
- 9.4.4 在請求之間存儲SecurityContext
- 9.5 Spring Security中的訪問控制(授權)
- 9.5.1 Security and AOP Advice
- 9.5.2 Secure Objects and the AbstractSecurityInterceptor
- 什么是配置屬性
- RunAsManager
- AfterInvocationManager
- 擴展安全對象模型
- 9.6 本地化
- 10 核心服務
- 10.1 The AuthenticationManager, ProviderManager and AuthenticationProvider
- 10.1.1 成功驗證時擦除憑據
- 10.1.2 DaoAuthenticationProvider
- 10.2 UserDetailsService實現
- 10.2.1 In-Memory Authentication
- 10.2.2 JdbcDaoImpl
- Authority Groups
- 10.3 Password Encoding
- 10.3.1 密碼發展史
- 10.3.2 DelegatingPasswordEncoder
- 密碼存儲格式
- 密碼編碼
- 密碼比對
- 入門體驗
- 排除故障
- 10.3.3 BCryptPasswordEncoder
- 10.3.4 Pbkdf2PasswordEncoder
- 10.3.5 SCryptPasswordEncoder
- 10.3.6 其他PasswordEncoders
- 10.4 Jackson的支持
- 11 測試方法安全
- 12 集成spring mvc測試
- 13 webflux支持
- 14 安全過濾器鏈
- 14.1 DelegatingFilterProxy
- 14.2 FilterChainProxy
- 14.2.1 繞過過濾鏈
- 14.3 過濾器順序
- 14.4 匹配請求和http防火墻
- 14.5 與其他基于過濾器的框架一起使用
- 14.6 Advanced Namespace Configuration
- 15. 核心的安全過濾器
- 15.1 FilterSecurityInterceptor
- 15.2 ExceptionTranslationFilter
- 15.3 SecurityContextPersistenceFilter
- 15.4 UsernamePasswordAuthenticationFilter