springsecurity的工作原理
結構總覽
Spring Security所解決的問題就是安全訪問控制,
而安全訪問控制功能其實就是對所有進入系統的請求進行攔截,校驗每個請求是否能夠訪問它所期望的資源。
根據前邊知識的學習,可以通過Filter或AOP等技術來實現,
Spring Security對Web資源的保護是靠Filter實現的,所以從這個Filter來入手,逐步深入Spring Security原理。
當初始化Spring Security時,會創建一個名為SpringSecurityFilterChain 的Servlet過濾器,
類型為org.springframework.security.web.FilterChainProxy,它實現了javax.servlet.Filter,
因此外部的請求會經過此類,下圖是Spring Security過濾器鏈結構圖:
FilterChainProxy是一個代理,
真正起作用的是FilterChainProxy中SecurityFilterChain所包含的各個Filter,
同時這些Filter作為Bean被Spring管理,它們是Spring Security核心,各有各的職責,
但他們并不直接處理用戶的認證,也不直接處理用戶的授權,
而是把它們交給了認證管理器(AuthenticationManager)和決策管理器(AccessDecisionManager)進行處理,
下圖是FilterChainProxy相關類的UML圖示。
spring Security功能的實現主要是由一系列過濾器鏈相互配合完成。
下面介紹過濾器鏈中主要的幾個過濾器及其作用:
SecurityContextPersistenceFilter 這個Filter是整個攔截過程的入口和出口(也就是第一個和最后一個攔截器),
???????????????????????????????????????????????????????? 會在請求開始時從配置好的 SecurityContextRepository 中獲取 SecurityContext,
?????????????????????????????????????????????????????? ? 然后把它設置給SecurityContextHolder。
???????????????????????????????????????????????????????? 在請求完成后將 SecurityContextHolder 持有的 SecurityContext 再保存到配置好的 SecurityContextRepository,
???????????????????????????????????????????????????????? 同時清除 securityContextHolder 所持有的 SecurityContext;
UsernamePasswordAuthenticationFilter 用于處理來自表單提交的認證。該表單必須提供對應的用戶名和密碼,
??????????????????????????????????????????????????????????????????? 其內部還有登錄成功或失敗后進行處理的 AuthenticationSuccessHandler 和 AuthenticationFailureHandler,這些都可以根據需求做相關改變;
FilterSecurityInterceptor? 是用于保護web資源的,使用AccessDecisionManager對當前用戶進行授權訪問
ExceptionTranslationFilter ? 能夠捕獲來自 FilterChain 所有的異常,并進行處理。但是它只會處理兩類異常:
??????????????????????????????????????????????? AuthenticationException 和 AccessDeniedException,其它的異常它會繼續拋出。
認證流程
AuthenticationProvider
通過前面的Spring Security認證流程得知,認證管理器(AuthenticationManager)委托AuthenticationProvider完成認證工作。
AuthenticationProvider是一個接口,定義如下:
在DaoAuthenticationProvider的基類???? AbstractUserDetailsAuthenticationProvider發現以下代碼:
public boolean supports(Class<?> authentication) {return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication); }也就是說當web表單提交用戶名密碼時,Spring Security由DaoAuthenticationProvider處理。
最后,我們來看一下Authentication(認證信息)的結構,
它是一個接口,我們之前提到的UsernamePasswordAuthenticationToken就是它的實現之一:
(1)Authentication是spring security包中的接口,直接繼承自Principal類,而Principal是位于java.security包中的。它是表示著一個抽象主體身份,任何主體都有一個名稱,因此包含一個getName()方法。
(2)getAuthorities(),權限信息列表,默認是GrantedAuthority接口的一些實現類,通常是代表權限信息的一系列字符串。
(3)getCredentials(),憑證信息,用戶輸入的密碼字符串,在認證過后通常會被移除,用于保障安全。
(4)getDetails(),細節信息,web應用中的實現接口通常為 WebAuthenticationDetails,它記錄了訪問者的ip地址和sessionId的值。
(5)getPrincipal(),身份信息,大部分情況下返回的是UserDetails接口的實現類,UserDetails代表用戶的詳細信息,
?????????? 那從Authentication中取出來的UserDetails就是當前登錄用戶信息,它也是框架中的常用接口之一。
UserDetailsService
1)認識UserDetailsService
現在咱們現在知道DaoAuthenticationProvider處理了web表單的認證邏輯,認證成功后既得到一個Authentication(UsernamePasswordAuthenticationToken實現),里面包含了身份信息(Principal)。
這個身份信息就是一個Object ,大多數情況下它可以被強轉為UserDetails對象。
DaoAuthenticationProvider中包含了一個UserDetailsService實例,它負責根據用戶名提取用戶信息UserDetails(包含密碼),
而后DaoAuthenticationProvider會去對比UserDetailsService提取的用戶密碼與用戶提交的密碼是否匹配作為認證成功的關鍵依據,
因此可以通過將自定義的UserDetailsService 公開為spring bean來定義自定義身份驗證。
public interface UserDetailsService {UserDetails loadUserByUsername(String username) throws UsernameNotFoundException; }很多人把DaoAuthenticationProvider和UserDetailsService的職責搞混淆,其實UserDetailsService只負責從特定的地方(通常是數據庫)加載用戶信息,僅此而已。
而DaoAuthenticationProvider的職責更大,它完成完整的認證流程,同時會把UserDetails填充至Authentication。
上面一直提到UserDetails是用戶信息,咱們看一下它的真面目:
它和Authentication接口很類似,
比如它們都擁有username,authorities。Authentication的getCredentials()與UserDetails中的getPassword()需要被區分對待,
前者是用戶提交的密碼憑證,后者是用戶實際存儲的密碼,認證
其實就是對這兩者的比對。
Authentication中的getAuthorities()實際是由UserDetails的getAuthorities()傳遞而形成的。
還記得Authentication接口中的getDetails()方法嗎?其中的UserDetails用戶詳細信息便是經過了AuthenticationProvider認證之后被填充的。
通過實現UserDetailsService和UserDetails,我們可以完成對用戶信息獲取方式以及用戶信息字段的擴展。
Spring Security提供的InMemoryUserDetailsManager(內存認證),JdbcUserDetailsManager(jdbc認證)就是UserDetailsService的實現類,主要區別無非就是從內存還是從數據庫加載用戶。
總結
以上是生活随笔為你收集整理的springsecurity的工作原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring Security 应用详解
- 下一篇: 报错信息为:Failed to conf