新聞中心
流程一致性
通常情況下所有的資源訪問都應(yīng)該是有條件的。用來驗(yàn)證這些條件的流程也應(yīng)該是一致的。我們來看實(shí)際生活中的一個(gè)例子,老王是一家公司的老板,他的車進(jìn)地下車庫是免費(fèi)的,其他人進(jìn)地下車庫是計(jì)費(fèi)的。我們來思考如何實(shí)現(xiàn)這個(gè)需求。

如果流程不一致的話,需要兩條道,一條是VIP通道(讓老王走),一條是大眾通道(給其他人用),這兩個(gè)通道的維護(hù)成本會(huì)很高,還有人會(huì)經(jīng)常走錯(cuò)道,甚至招致不滿,憑啥他要搞特權(quán);如果流程一致,這事就好辦多了,不管是誰都得按同一個(gè)通道流程進(jìn)入停車場,只需要維護(hù)一個(gè)VIP標(biāo)簽就行了,成本大大降低,流程也簡化了,還顯得老王沒有架子。這個(gè)VIP標(biāo)簽就是所謂的“匿名用戶”。
Spring Security匿名用戶
Spring Security中專門設(shè)計(jì)了匿名用戶,它的作用其實(shí)也是為了在保證流程一致的前提下去執(zhí)行一些特殊的認(rèn)證邏輯,比如程序的登錄、主頁的數(shù)據(jù)接口,這些未認(rèn)證的用戶場景需要繞過訪問控制檢查,通過引入一個(gè)特殊的“匿名身份”可以做到這一點(diǎn),匿名用戶可以做什么、不可以做什么都可以輕松定義, 這就是我們所說的匿名身份驗(yàn)證。
請(qǐng)注意:“經(jīng)過匿名身份驗(yàn)證”的用戶和未經(jīng)身份驗(yàn)證的用戶之間沒有真正的差異,你可以認(rèn)為匿名用戶就是未認(rèn)證用戶,你也可以認(rèn)為匿名用戶是執(zhí)行了匿名認(rèn)證流程后的認(rèn)證用戶。
匿名用戶的配置
匿名用戶是認(rèn)證體系最后的一道認(rèn)證流程,負(fù)責(zé)匿名認(rèn)證的過濾器是AnonymousAuthenticationFilter,當(dāng)發(fā)現(xiàn)請(qǐng)求不具備任何其它認(rèn)證條件后,會(huì)生成一個(gè)AnonymousAuthenticationToken,它包含三個(gè)屬性:
keyHash 僅僅在AnonymousAuthenticationFilter和AnonymousAuthenticationProvider之間共享, 以避免一些惡意客戶端去偽造AnonymousAuthenticationToken。
權(quán)限控制只需要針對(duì)ROLE_ANONYMOUS進(jìn)行限制即可,也可以通過認(rèn)證投票器AuthenticatedVoter的IS_AUTHENTICATED_ANONYMOUSLY屬性來限制。
下面這幾種配置都可以用來控制匿名用戶的訪問權(quán)限:
http
.authorizeRequests()
.mvcMatchers("/anonymous0").access("hasAuthority('ROLE_USER')")
.mvcMatchers("/anonymous1").hasAuthority("ROLE_ANONYMOUS")
.mvcMatchers("/anonymous2").hasRole("ANONYMOUS")
.mvcMatchers("/anonymous3").access("isAnonymous()")
.mvcMatchers("/anonymous4").access("IS_AUTHENTICATED_ANONYMOUSLY")
.mvcMatchers("/anonymous5").anonymous()
獲取匿名用戶
Spring MVC中使用它自己的參數(shù)解析器來獲取當(dāng)前Principal:
@GetMapping("/")
public String method(Authentication authentication) {
if (authentication instanceof AnonymousAuthenticationToken) {
return "anonymous";
} else {
return "not anonymous";
}
}
以上方式將永遠(yuǎn)返回not anonymous,即使是匿名請(qǐng)求。如果您想獲取匿名請(qǐng)求的Authentication,請(qǐng)改用@CurrentSecurityContext:
@GetMapping("/")
public String method(@CurrentSecurityContext SecurityContext context) {
Authentication authentication = context.getAuthentication()
if (authentication instanceof AnonymousAuthenticationToken) {
return "anonymous";
} else {
return "not anonymous";
}
}
你想一想還有沒有其它方式去獲得匿名用戶?
文章題目:聊聊我們?yōu)槭裁匆O(shè)計(jì)匿名用戶
文章路徑:http://m.5511xx.com/article/codhpho.html


咨詢
建站咨詢
