Spring-Security

Spring-Security是spring的一個權限管理框架,對於我們需要知道的就是他的認證和授權功能。spring3+對於其整個權限管理架構的過濾器鏈已經進行了屏蔽。我們可以對器過濾器鏈的某個進行修改獲得與我們業務更加合拍的權限管理,我們需要關心的就是spring-security的兩個功能,認證和授權。他和Acegi security的認證架構是一致的,不過Acegi security不再進行更新。

認證,對於認證spring提供了不同層次的認證,順序爲:①數字證書認證(X509_FILTER)②CAS認證CAS_FILTER③用戶登錄域的驗證(FORM_LOGIN_FILTER),這也是我們經常使用的驗證,對於不是特定的需求,我們一般不進行數字證書等的驗證。而只是對其username和password進行驗證。

username/password的認證我們使用的是【FORM_LOGIN_FILTER】這個過濾器。這一個過濾器默認的實現類是UsernamePasswordAuthenticationFilter,其繼承了AbstractAuthenticationProcessingFilter類,主要的作用爲:①判斷url請求是否是一個認證請求(默認的認證請求是j_spring_security_check)②對於是認證的請求則進行前期數據判斷(for-example:username,password is not null)③創建一個未經認證的Authenticate對象,例如:UsernamePasswordAuthenticationToken對象,其繼承【AbstractAuthenticationToken】,將用戶名、密碼存入其中,可以以UserDetails的對象形式存儲,這時我們自定義的authentication中getName方法就要好好寫,以後的用戶名來源於此方法。④setDetails()使用創建一個額外信息的保存,例如sessionId等主要存放的是request的一些詳情;⑤將未認證的Authenticate交予與之關聯的認證管理器進行認證⑥對認證通過的對象保存在SecurityContextHolder容器中。⑦多人登錄的限制問題session控制, sessionStrategy.onAuthentication(authResult,request, response);

認證管理器中提供了一些列的provider,我們在FORM_LOGIN_FILTER過濾器中創建的未認證的authentication對象會選擇一個provider進行認證,認證管理器要做的就是對於不同的authenticate交給不同的認證管理器進行認證,因此每一個provider需要說明其適合於認證哪一種authenticate,所以對於provider需要複寫一個方法supports(Class <? extend Object>),Class中isAssignableFrom(Class)判定此Class 對象所表示的類或接口與指定的Class 參數所表示的類或接口是否相同,或是否是其超類或超接口。

對於合適的provider需要對未認證的Authenticate進行認證,一個provider跟一個userDetailsService進行關聯。userDetailsService將根據用戶名來加載用戶信息(loadUserDetailsByUsername(String username)),返回一個UserDetails對象。provider會從userDetails對象中提取password和我們未認證的對象中的密碼進行比對,成功則創建一個已認證的對象返回。

  對於認證通過的對象,那麼Authenticate中認證標示是true。這時候其SecurityIntercept過濾器會對這個給對象的訪問權限進行判斷和授權。具體爲:①判定Authenticate對象是否爲已經認證通過,如果沒有,調用認證管理器進行認證。②創建安全環境,將認證通過的{對象、request、response}等包裝成一個security0bject對象。這個對象需要繼承AbstractSecurityIntercept.③將安全對象(securityObject)交予與之關聯的訪問決策器accessDecisionManager進行決策。對於授權的這個過濾器其實在服務器啓動的時候他就知道了所有的ConfigAttribute(配置屬性,使用Map存儲),當我們進行請求授權的時候,我們傳遞過去的安全對象可以解析出一個url,根據這個url使用urlMarcher去返回一個你請求的配置屬性。這樣將配置屬性使用getAttribute()方法獲得你訪問所需的權限,再使用已認證的Authentication中的getAuthority()方法獲得你已經擁有的權限進行對比,看一下你是否有權限訪問。

ConfigAttribute和Authority對象相似,都提供了僅僅一個返回String的方法。

決策管理器用來對一個安全對象的請求給予合適的投票器①從securityObject中獲得其請求的安全環境屬性(ConfigAttribute)②從Authenticate對象中獲取GrantAuthority數組對象。③交給投票器鏈頭投票,策管理器中有多個voter,其有一個supports對象,用來指定這個voter用來對那個ConfigAttribute進行vote。

voter(投票器),隸屬於決策管理器中,給特定的ConfigAttribute進行投票。同意 1,中立 0,拒絕 -1。對於自己管轄的ConfigAttribute進行投票(1或-1),對於不是自己管轄的ConfigAttribute則返回中立。對於投票成功將有訪問的權利。

UserDetails和Authentication對象的關聯

①  通過一個未認證的Authentication中的getName方法獲取用戶名,根據用戶名UserDetailsService可以返回一個UserDetails對象,UserDetails對象中的getAuthorities()方法獲得的權限集將會給Authentication對象

②  UserDetails對象中的getUsername和getPassword方法可以獲得真正的數據用戶名和密碼,他和Authentication對象中的getCredentials()得到的密碼進行比較,獲得商戶是否正確的一個說法,當然有passwordEncoder的使用會將getCredentials()獲得的密碼在加密後比較

③  對於UserDetails對象我們還可以保存在已認證的Authentication中。

④  如果認證的時候我們傳遞了一個未認證的authentication對象,回來的時候我們也有個已近認證的authentication對象,但這兩個對象不是同一個,沒任何管理。返回來的authentication對象中getPrincipal();就是我們userDetails對象,而未認證的authentication對象中這個方法我們僅僅存儲了一個字符串。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章