spring security 匿名登錄


匿名登錄,即用戶尚未登錄系統,系統會為所有未登錄的用戶分配一個匿名用戶,這個用戶也擁有自己的權限,不過他是不能訪問任何被保護資源的。

設置一個匿名用戶的好處是,我們在進行權限判斷時,可以保證SecurityContext中永遠是存在着一個權限主體的,啟用了匿名登錄功能之后,我們所需要做的工作就是從SecurityContext中取出權限主體,然后對其擁有的權限進行校驗,不需要每次去檢驗這個權限主體是否為空了。這樣做的好處是我們永遠認為請求的主體是擁有權限的,即便他沒有登錄,系統也會自動為他賦予未登錄系統角色的權限,這樣后面所有的安全組件都只需要在當前權限主體上進行處理,不用一次一次的判斷當前權限主體是否存在。這就更容易保證系統中操作的一致性

1. 配置文件

在配置文件中使用auto-config="true"就會啟用匿名登錄功能。在啟用匿名登錄之后,如果我們希望允許未登錄就可以訪問一些資源,可以在進行如下配置。

<http auto-config='true'>
    <intercept-url pattern="/" access="IS_AUTHENTICATED_ANONYMOUSLY" />
    <intercept-url pattern="/admin.jsp" access="ROLE_ADMIN" />
    <intercept-url pattern="/**" access="ROLE_USER" />
</http>

在access中指定IS_AUTHENTICATED_ANONYMOUSLY后,系統就知道此資源可以被匿名用戶訪問了。當未登錄時訪問系統的“/”,就會被自動賦以匿名用戶的身份。我們可以使用taglib獲得用戶的權限主體信息。

這里的IS_AUTHENTICATED_ANONYMOUSLY將會交由AuthenticatedVoter處理,內部會依據AuthenticationTrustResolver判斷當前登錄的用戶是否是匿名用戶。

在access中指定IS_AUTHENTICATED_ANONYMOUSLY后,系統就知道此資源可以被匿名用戶訪問了。當未登錄時訪問系統的“/”,就會被自動賦以匿名用戶的身份。我們可以使用taglib獲得用戶的權限主體信息。

這里的IS_AUTHENTICATED_ANONYMOUSLY將會交由AuthenticatedVoter處理,內部會依據AuthenticationTrustResolver判斷當前登錄的用戶是否是匿名用戶。

 
        

當用戶訪問系統時,就會看到如下信息,這時他還沒有進行登錄。

匿名登錄

圖 17.1. 匿名登錄

 

這里顯示的是分配給所有未登錄用戶的一個默認用戶名roleAnonyMous,擁有的權限是ROLE_ANONYMOUS。我們可以看到系統已經把匿名用戶當做了一個合法有效的用戶進行處理,可以獲得它的用戶名和擁有的權限,而不需判斷SecurityContext中是否為空。

實際上,我們完全可以把匿名用戶像一個正常用戶那樣進行配置,我們可以在配置文件中直接使用ROLE_ANONYMOUS指定它可以訪問的資源。

<http auto-config='true'>
    <intercept-url pattern="/" access="ROLE_ANONYMOUS" />
    <intercept-url pattern="/admin.jsp" access="ROLE_ADMIN" />
    <intercept-url pattern="/**" access="ROLE_USER" />
</http>
        

不過,為了更明顯的將匿名用戶與系統中的其他用戶區分開,我們推薦在配置時盡量使用IS_AUTHENTICATED_ANONYMOUSLY來指定匿名用戶可以訪問的資源。

2. 修改默認用戶名

我們通常可以看到這種情況,當一個用戶尚未登錄系統時,在頁面上應當顯示用戶名的部分顯示的是“游客”。這樣操作更利於提升客戶體驗,他看到自己即使沒有登錄也可以使用“游客”的身份享受系統的服務,而且使用了“游客”作為填充內容,也避免了原本顯示用戶名部分留空,影響頁面布局。

如果沒有匿名登錄的功能,我們就被迫要在所有顯示用戶名的部分,判斷當前用戶是否登錄,然后根據登錄情況顯示登錄用戶名或默認的“游客”字符。匿名登錄功能幫我們解決了這個問題,既然未登錄用戶都擁有匿名用戶的身份,那么在顯示用戶名時就不必去區分用戶登錄狀態,直接顯示當前權限主體的名稱即可。

我們需要做的只是為匿名設置默認的用戶名而已,默認的名稱roleAnonymous可以通過配置文件中的anonymous元素修改。

<http auto-config='true'>
    <intercept-url pattern="/" access="IS_AUTHENTICATED_ANONYMOUSLY" />
    <intercept-url pattern="/admin.jsp" access="ROLE_ADMIN" />
    <intercept-url pattern="/**" access="ROLE_USER" />
    <anonymous username="Guest"/>
</http>
        

這樣,匿名用戶的默認名稱就變成了“Guest”,我們在頁面上依然使用相同的taglib顯示用戶名即可。

修改匿名用戶名稱

3. 匿名用戶的限制

雖然匿名用戶無論在配置授權時,還是在獲取權限信息時,都與已登錄用戶的操作一模一樣,但它應該與未登錄用戶是等價,當我們以匿名用戶的身份進入“/”后,點擊admin.jsp鏈接,系統會像處理未登錄用戶時一樣,跳轉到登錄用戶,而不是像處理以登錄用戶時顯示拒絕訪問頁面。

但是匿名用戶與未登錄用戶之間也有很大的區別,比如,我們將“/”設置為不需要過濾器保護,而不是設置匿名用戶。

<http security="none" pattern="/"/>

<http auto-config='true'>
    <intercept-url pattern="/" access="IS_AUTHENTICATED_ANONYMOUSLY" /> <intercept-url pattern="/admin.jsp" access="ROLE_ADMIN" /> <intercept-url pattern="/**" access="ROLE_USER" /> </http> 

security="none"表示當我們訪問“/”時,是不會使用任何一個過濾器去處理這個請求的,它可以實現無需登錄即可訪問資源的效果,但是因為沒有使用過濾器對請求進行處理,所以也無法利用安全過濾器為我們帶來的好處,最簡單的,這時SecurityContext內再沒有保存任何一個權限主體了,我們也無法從中取得主體名稱以及對應的權限信息。

跳過過濾器的情況

圖 17.3. 跳過過濾器的情況


因此,使用security="none"忽略所有過濾器會提升性能,而是用匿名登錄功能可以實現權限操作的一致性,具體應用時還需要大家根據實際情況自行選擇了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM