springSecurity安全框架的學習和原理解讀

一、Spring security框架簡介

1、簡介
一個能夠爲基於Spring的企業應用系統提供聲明式的安全訪問控制解決方式的安全框架(簡單說是對訪問權限進行控制嘛),應用的安全性包括用戶認證(Authentication)用戶授權(Authorization) 兩個部分。
①用戶認證指的是驗證某個用戶是否爲系統中的合法主體,也就是說用戶能否訪問該系統。用戶認證一般要求用戶提供用戶名和密碼。系統通過校驗用戶名和密碼來完成認證過程。
② 用戶授權指的是驗證某個用戶是否有權限執行某個操作。在一個系統中,不同用戶所具有的權限是不同的。比如對一個文件來說,有的用戶只能進行讀取,而有的用戶可以進行修改。一般來說,系統會爲不同的用戶分配不同的角色,而每個角色則對應一系列的權限。
spring security的主要核心功能爲 認證和授權,所有的架構也是基於這兩個核心功能去實現的。

2、框架原理
衆所周知 想要對對Web資源進行保護,最好的辦法莫過於Filter,要想對方法調用進行保護,最好的辦法莫過於AOP。所以springSecurity在我們進行用戶認證以及授予權限的時候,通過各種各樣的攔截器來控制權限的訪問,從而實現安全。
對Web資源的保護,就是靠Filter實現的。如下圖:在這裏插入圖片描述
一般來說,我們的Filter都是配置在web.xml中,但是springSecurity不一樣,它在web.xml中配置的只是一個代理,而真正起作用的Filter是作爲Bean配置在Spring中的。web.xml中的代理依次調用這些Bean,就實現了對Web資源的保護,同時這些Filter作爲Bean被Spring管理,所以實現AOP也很簡單,真的是一舉兩得啊。

springSecurity中提供的Filter不少,有十多個,一個一個學起來比較複雜。但是對於我們Web開發者來說,常用的就那麼幾個,如下圖中的被紅圈圈標記出來的:
在這裏插入圖片描述
從上到下,它們實現的功能依次是1、制定必須爲https連接;2、從Session中提取用戶的認證信息;3、退出登錄;4、登錄;5、記住用戶;6、所有的應用必須配置這個Filter。

一般來說,我們寫Web應用只需要熟悉這幾個Filter就可以了,如果不需要https連接,連第一個也不用熟悉。但是有人肯定會想,這些Filter怎麼和我的數據庫聯繫起來呢?(解釋:爲什麼要和數據庫相聯繫的原因是“這些權限信息都保存在數據庫中,哪些用戶有這些權限,哪有用戶有那些權限,這些數據信息都是存留在數據庫中的”)不用着急,這些Filter並不直接處理用戶的認證,也不直接處理用戶的授權,而是把它們交給了認證管理器和決策管理器。如下圖:
在這裏插入圖片描述
對於這兩種管理器,那也是不需要我們寫代碼的,Acegi也提供了現成的類。那麼大家又奇怪了:又是現成的,那怎麼和我的數據庫關聯起來呢?彆着急,其實這兩個管理器自己也不做事,認證管理器把任務交給了Provider,而決策管理器則把任務交給了Voter,如下圖:
在這裏插入圖片描述
現在我要告訴你們,這裏的Provider和Voter也是不需要我們寫代碼的。不要崩潰,快到目標了。Acegi提供了多個Provider的實現類,如果我們想用數據庫來儲存用戶的認證數據,那麼我們就選擇DaoAuthenticationProvider。對於Voter,我們一般選擇RoleVoter就夠用了,它會根據我們配置文件中的設置來決定是否允許某一個用戶訪問制定的Web資源。

而DaoAuthenticationProvider也是不直接操作數據庫的,它把任務委託給了UserDetailService,如下圖:
在這裏插入圖片描述
而我們要做的,就是實現這個UserDetailService。 圖畫得不好,大家不要見笑,但是說了這麼多總算是引出了我們開發中的關鍵, 那就是我們要實現自己的UserDetailService,它就是連接我們的數據庫和Acegi的橋樑。 UserDetailService的要求也很簡單,只需要一個返回org.springframework.security.userdetails.User對象的loadUserByUsername(String userName)方法。因此,怎麼設計數據庫都可以,不管我們是用一個表還是兩個表還是三個表,也不管我們是用戶-授權,還是用戶-角色-授權,還是用戶-用戶組-角色-授權,這些具體的東西Acegi統統不關心,它只關心返回的那個User對象。至於怎麼從數據庫中讀取數據,那就是我們自己的事了。

反過來再看看上面的過程,我們發現,即使我們要做的只是實現自己的UserDetailService類,但是我們不得不在Spring中配置那一大堆的Bean,包括幾個Filter,幾個Manager,幾個Provider和Voter,而這些配置往往都是重複的無謂的。好在springSecurity 2.0也認識到了這個問題,所以,它設計了一個標籤,讓springSecurity的配置得到了簡化。下面是SpringSide 3中的配置的截圖,大家可以看看:
在這裏插入圖片描述
下圖是官方文章中的傳統Filter設置和元素之間的對應關係:
在這裏插入圖片描述
下面的代碼是SpringSide 3中實現UserDetailService的範例,在SpringSide 3的範例中,筆者使用了三個表User、Role、Authority。但是springSecurity不關心你用了幾個表,它只關心UserDetails對象。而決定用戶能否訪問指定Web資源的是RoleVoter類,無需任何修改它可以工作得很好,唯一的缺點是它只認ROLE_前綴,所以搞得筆者的Authority看起來都象角色,不倫不類。
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
最後再來說說這個命名的問題,我對Authentication和Authority這兩個單詞比較反感,兩個原因,一是因爲它們太生僻了,二是因爲它們長得太像了,明明一個是認證,一個是授權,意思相差很遠,外貌卻如此相似,確實很煩人。如果讓我來選擇,我喜歡Privilege這個單詞,在我剛使用MySQL的時候就跟它很熟了,所以在我的項目中,我可能會用Privilege來代替Authority。如果我們只使用User-Role兩級關係,使用RoleVoter默認的ROLE_前綴當然沒有關係,如果是像筆者這樣是用三層關係,最好還是把這個前綴改一改,以免混淆。

補充:
前文所講的是我對springSecurity的一些理解,我認爲只有把條理搞清楚了,才更容易深入。我想得比較簡單,當然會漏掉一些細節。這裏把它補充一下。

1、我上面講到的主要內容,包含了認證和授權,但是漏掉了資源,資源就是我們需要保護的URL,或者一些類中的方法。要保護URL,在xml文件中按照前面的例子配置就可以了,要保護類中的方法,使用@secured就可以了。
但是它們是和Acegi中的哪個組件關聯起來的呢?是FilterSecurityInterceptor和MethodSecurityInterceptor,這兩個Interceptor都需要設置一個叫objectDefinitionSource的屬性。所以,有人要問,如何把對資源的保護設置全部轉移到數據庫中,避免寫在xml中,那就要從這個objectDefinitionSource着手了。

2、前面講到了UserDetailService,事實上在Acegi中還需要配置別的Service,如RememberMeService,當然,該Service也是現成的,不需要我們寫代碼的,RememberMeProcessingFilter需要依賴這個Service。

3、springSecurity支持OpenID和CAS 3,這兩個東西是幹什麼的呢?是可以實現單點登錄功能的,也就是允許用戶只登錄一次,就可以使用多個網站。這對於那些很龐大的網站非常有用,可以把用戶登錄這樣的操作集中在一臺服務器上。要使用CAS,只需要配置Filter時選擇CASProcessingFilte,配置Provider時選擇CasAuthenticationProvider,其餘的概念都是相通的。具體的實現細節,大家慢慢摸索吧。

如果不喜歡ROLE_這個前綴,可以通過下面的方式來替換
在這裏插入圖片描述

二、自定義安全配置的加載機制

1、前提 基於自身業務需要
有關springSecrity安全框架的理解參考:springSecurity安全框架介紹

未完待續:https://blog.csdn.net/liushangzaibeijing/article/details/81220610#     2、框架原理

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