`AuthenticationManager`只是一個接口,
~~~
Authentication authenticate(Authentication authentication)
throws AuthenticationException;
~~~
因此實現可以是我們選擇的任何東西,但它在實踐中如何工作?如果我們需要檢查多個身份驗證數據庫或不同身份驗證服務(如數據庫和LDAP服務器)的組合,該怎么辦?
`AuthenticationProvider`也是一個接口,和`AuthenticationManager`的功能一樣,實現認證,但是多了一個方法
~~~
boolean supports(Class<?> authentication);
~~~
如果支持特定類型的authentication,則返回true,但是不代表一定能驗證通過,authenticate方法仍然可以返回null.
Spring Security中的默認實現稱為`ProviderManager`,它不是處理身份驗證請求本身,而是委托給已配置的`AuthenticationProvider`列表,然后依次查詢每個查看是否可以執行身份驗證。每個提供程序將拋出異常或返回完全填充的`Authentication`對象。還記得我們的好朋友,`UserDetails`和`UserDetailsService`嗎?如果沒有,請回到上一章并刷新記憶。驗證身份驗證請求的最常用方法是加載相應的`UserDetails`并檢查加載的密碼與用戶輸入的密碼。這是`DaoAuthenticationProvider`使用的方法(見下文)。加載的`UserDetails`對象 - 特別是它包含的`GrantedAuthority`(角色) - 將在構建完全填充的`Authentication`對象時使用,該對象從成功的身份驗證返回并存儲在`SecurityContext`中。
如果您正在使用命名空間,則會在內部創建和維護`ProviderManager`的實例,并使用身份驗證命名空間提供程序元素向其添加提供程序(請參閱命名空間章節)。在這種情況下,您不應在應用程序上下文中聲明`ProviderManager `bean。但是,如果您沒有使用命名空間,那么您將聲明它如下:
~~~
<bean id="authenticationManager"
class="org.springframework.security.authentication.ProviderManager">
<constructor-arg>
<list>
<ref local="daoAuthenticationProvider"/>
<ref local="anonymousAuthenticationProvider"/>
<ref local="ldapAuthenticationProvider"/>
</list>
</constructor-arg>
</bean>
~~~
在上面的例子中,我們有三個提供者。它們按所示順序(使用`List`暗示)進行嘗試,每個提供程序都可以嘗試進行身份驗證,或者通過簡單地返回`null`來跳過身份驗證。如果所有實現都返回null,則`ProviderManager`將拋出`ProviderNotFoundException`。如果您有興趣了解有關鏈接提供程序的更多信息,請參閱`ProviderManager` Javadoc。
諸如Web表單登錄處理過濾器之類的身份驗證機制將引用`ProviderManager`,并將其調用以處理其身份驗證請求。您需要的提供程序有時可以與身份驗證機制互換,而在其他時候,它們將依賴于特定的身份驗證機制。例如,`DaoAuthenticationProvider`和`LdapAuthenticationProvider`與提交簡單用戶名/密碼身份驗證請求的任何機制兼容,因此可以使用基于表單的登錄或HTTP基本身份驗證。另一方面,某些身份驗證機制會創建一個身份驗證請求對象,該對象只能由單一類型的`AuthenticationProvider`進行解釋。一個例子是JA-SIG CAS,它使用服務票據的概念,因此只能由`CasAuthenticationProvider`進行身份驗證。您不必過于擔心這一點,因為如果您忘記注冊合適的提供程序,那么在嘗試進行身份驗證時,您只會收到`ProviderNotFoundException`。
- 架構
- 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