shiro安全控制目錄
在構(gòu)建一個系統(tǒng)的時候,權(quán)限管理和用戶認證是最基本的功能。而用戶認證就是一個比較常見的模塊。在已有的方案中,我們最常見的就是保存到tomcat的session對象中,而隨著微服務(wù)的興起,一種新的認證方式又火了起來,那就是JWT。
序 Session和Token的區(qū)別:
1. session出現(xiàn)的原因
因為http協(xié)議是無狀態(tài)的,所以服務(wù)端不能判斷本次請求和上次請求是不是同一個人操作的,故使用cookie和session來維護客戶狀態(tài)。
2. session生成的方式
瀏覽器在第一次訪問服務(wù)器時,服務(wù)器創(chuàng)建一個session,然后同時為該session生成一個唯一的會話sessionId,然后將sessionId和session存儲到Redis/內(nèi)存中,然后服務(wù)器再把sessionId(名字為JESSIONID的cookie),以cookie形式發(fā)送給客戶端。
瀏覽器再次訪問時會攜帶cookie中的sessionId,然后服務(wù)器根據(jù)sessionId找到對應(yīng)的session進行匹配。如果瀏覽器禁用了cookie/不支持cookie,可以通過URL重寫的方式發(fā)送到服務(wù)器。
3. token出現(xiàn)的原因
session的存儲是需要空間的,session的傳輸一般都是通過cookie來傳輸,或url重寫的方式。而token在服務(wù)器時可以不存儲用戶信息的,token傳遞的方式也不限于cookie傳遞,token也可以保存起來。
4. token和session的區(qū)別
共同點:都是保存了用戶身份信息,都有過期時間。
session是會話,而token是令牌。
session是空間換時間,token是時間換空間。
session和sessionId:服務(wù)器會保存一份,可能保存到緩存/數(shù)據(jù)庫/文件。
token:服務(wù)器不需要記錄任何東西,每次都是一個無狀態(tài)的請求,每次都是通過解密算法來驗證是否合法。
sessionId:一般是隨機字符串,要到服務(wù)器檢索id的有效性。
1. 兩種認證方式的區(qū)別
當(dāng)一個設(shè)備(客戶端)向一個設(shè)備(服務(wù)端)發(fā)送請求的時候,服務(wù)端如何判斷這個客戶端是誰?傳統(tǒng)意義上的認證方式又兩種:有狀態(tài)認證、無狀態(tài)認證。有狀態(tài)認證和無狀態(tài)認證最大的區(qū)別就是服務(wù)器會不會保存客戶端的信息。
2. 有狀態(tài)認證
有狀態(tài)認證,以cookie-session模型為例,當(dāng)客戶端第一次請求服務(wù)端的時候,服務(wù)端會返回客戶端一個唯一的標(biāo)識(默認在cookie中),并保存對應(yīng)的客戶端信息,客戶端接受到唯一標(biāo)識之后,將標(biāo)識保存到本地cookie中,以后的每次請求都攜帶此cookie,服務(wù)器根據(jù)此cookie標(biāo)識就可以判斷請求的用戶是誰,然后查到對應(yīng)用戶的信息。

請求認證過程(以tomcat為例)
- 客戶端向服務(wù)器發(fā)送請求;
- 第一次客戶端發(fā)起請求,服務(wù)器創(chuàng)建一個key為
SESSIONID的值,并寫入到客戶端的cookie中,同時在服務(wù)器的Session Manager中創(chuàng)建一個對象,保存這個JESSIONID對應(yīng)的信息。 - 以后客戶端每次請求,都會根據(jù)cookie進行區(qū)別,我們可以通過session.setAttribute,session.getAttribute等方法擴展用戶信息,根據(jù)用戶信息做一些業(yè)務(wù)判斷。
- Session Manager中維護一個定時器,當(dāng)SESSIONID對應(yīng)的信息長時間沒有訪問(默認30分鐘),或者顯式調(diào)用session.invalidate方法,那么這個對應(yīng)的信息就會被刪除。
SESSION認證優(yōu)勢
因為客戶端信息都保存在服務(wù)器的Session Manager中,如果將客戶端的認證信息取消,只需要將Session中對應(yīng)信息刪除即可,及時相應(yīng),方便快捷。
SESSION認證劣勢
本質(zhì)上是以空間換時間。
- 因為服務(wù)端保存著客戶端的信息,當(dāng)用戶量特別多時候,服務(wù)端需要特別的內(nèi)存資源;
- 如果失效時間特別長的情況下,大量資源被占用無法釋放,如果釋放,那么相當(dāng)于用戶的注銷登錄;
- 客戶端的信息在服務(wù)端中維護,如果服務(wù)端為集群的場景下,那么客戶端信息不共享,必須使用分布式 session 或者其他方案;
- cookie有同源策略和跨域限制,部分業(yè)務(wù)場景下cookie并不能傳遞;
- 部分設(shè)備本身不支持cookie或者禁用cookie,還有的手機瀏覽器也不支持cookie。
Shiro有狀態(tài)身份認證——會話管理(整合Redis實現(xiàn)共享Session)
3. 無狀態(tài)認證
無狀態(tài)的認知,客戶端在提交身份信息,服務(wù)端驗證身份后,根據(jù)一定的算法生成一個token令牌返回給客戶端,之后每次請求服務(wù)端,客戶端都需要攜帶此令牌,服務(wù)器接受到令牌之后進行校驗,校驗通過后,提取令牌的信息用來區(qū)別用戶。

請求認知過程
- 執(zhí)行登錄操作,用戶端發(fā)送賬號密碼等信息。
- 服務(wù)端校驗賬號密碼是否正確,如果正確,根據(jù)對應(yīng)的用戶信息和服務(wù)端秘鑰生成JWT令牌,然后通過response.setHeader返回給客戶端(此處假設(shè)生成一個名為x-auth-token的令牌)。
- 客戶端在返回成功之后,將Header中的x-auth-token保存到本地中。
- 客戶端在以后每次請求服務(wù)器的時候,都會在header中攜帶x-auth-token令牌的值。
- 服務(wù)端每接受到請求之后,判斷hader中是否包含x-auth-token,token 是否有效,然后通過 BASE 64 算法 decode,根據(jù)解密后的參數(shù),判斷當(dāng)前 token 是否在有效期,所訪問的接口是否有權(quán)限等操作。
優(yōu)勢
- 因為服務(wù)器不保留客戶端的任何信息,每次只需要通過特定的算法進行校驗,節(jié)省了大量的存儲空間。
- 方便水平擴容,不需要 SSO Server,只要保證新的應(yīng)用采用同樣的驗證算法,就可以驗證通過并獲得對應(yīng)信息。
劣勢
本質(zhì)上是以時間換空間
當(dāng)客戶端的token被盜用,或者需要手動封禁某個用戶的時候,沒辦法對此token進行操作,必須等待token失效(如果在服務(wù)端維護token和用戶的關(guān)系,技術(shù)可以實現(xiàn),但是違背無狀態(tài)的設(shè)計理念)。
本文參考: