分析JWT的用法,根據(jù)其優(yōu)缺點找出一種合適的實戰(zhàn)方案,并將其引入到Spring Security中颠区。
一、傳統(tǒng)的session認(rèn)證
??在服務(wù)器存儲一份用戶登錄信息通铲,這份登錄信息會在響應(yīng)時傳遞給瀏覽器毕莱,告訴其保存cookie,以便下次請求時發(fā)送給我們的應(yīng)用颅夺。
Session: 每個用戶經(jīng)過我們的應(yīng)用認(rèn)證之后朋截,我們的應(yīng)用都要在服務(wù)端做一次記錄,以方便用戶下次請求的鑒別吧黄,通常而言session都是保存在內(nèi)存中部服,而隨著認(rèn)證用戶的增多,服務(wù)端的開銷會明顯增大拗慨。
擴展性: 用戶認(rèn)證之后廓八,服務(wù)端做認(rèn)證記錄奉芦,如果認(rèn)證的記錄被保存在內(nèi)存中的話,這意味著用戶下次請求還必須要請求在這臺服務(wù)器上,這樣才能拿到授權(quán)的資源剧蹂,這樣在分布式的應(yīng)用上声功,相應(yīng)的限制了負(fù)載均衡器的能力。這也意味著限制了應(yīng)用的擴展能力宠叼。
CSRF: 因為是基于cookie來進行用戶識別的, cookie如果被截獲先巴,用戶就會很容易受到跨站請求偽造的攻擊。
一冒冬、簡析JWT
1.JWT簡介
??定義了一種簡潔的筹裕,自包含的方法用于通信雙方之間以Json對象的形式安全的傳遞信息。
??1)簡潔(Compact): 可以通過URL窄驹,POST參數(shù)或者在HTTP header發(fā)送朝卒,因為數(shù)據(jù)量小,傳輸速度也很快
??2)自包含(Self-contained):負(fù)載中包含了所有用戶所需要的信息乐埠,避免了多次查詢數(shù)據(jù)庫
2.JWT的結(jié)構(gòu)
??JWT包含了使用.分割的三部分:Header(頭部)抗斤、Payload(載荷)、Signature(簽名)丈咐。其結(jié)構(gòu)看起來是這樣的:
xxx.yyy.zzz
Header
??在header中包含兩部分:token類型和采用的加密算法瑞眼,對這部分內(nèi)容使用Base64Url編碼后作為JWT結(jié)構(gòu)的第一部分。
{
"alg": "HS256",
"typ": "JWT"
}
Payload
??載荷包含三種類型的claim:reserved棵逊、public和private伤疙。將載荷經(jīng)過Base64Url編碼后作為JWT結(jié)構(gòu)的第二部分。
Reserved claims: 這些claim是JWT預(yù)先定義的辆影,在JWT中并不會強制使用它們徒像,而是推薦使用,常用的有 iss(Issuser蛙讥,簽發(fā)者), exp(Expiration time锯蛀,過期時間戳), sub(Subject,面向的用戶), aud(Audience次慢,接收方), iat(Issued at旁涤,簽發(fā)時間),nbf(Not Before):是一個時間戳迫像,代表這個JWT生效的開始時間劈愚,意味著在這個時間之前驗證JWT是會失敗的。
Public claims:根據(jù)需要定義自己的字段闻妓,注意應(yīng)該避免沖突
Private claims:這些是自定義的字段菌羽,可以用來在雙方之間交換信息
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
Signature
??創(chuàng)建簽名需要使用編碼后的header、payload以及一個秘鑰纷闺,使用header中指定簽名算法進行簽名算凿。如下使用HMAC SHA256算法:
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
簽名用于驗證消息的發(fā)送者以及消息是沒有經(jīng)過篡改的。
在身份鑒定的實現(xiàn)中犁功,傳統(tǒng)方法是在服務(wù)端存儲一個session氓轰,給客戶端返回一個cookie,而使用JWT之后浸卦,當(dāng)用戶使用它的認(rèn)證信息登陸系統(tǒng)之后署鸡,會返回給用戶一個JWT,用戶只需要本地保存該token(通常使用local storage限嫌,也可以使用cookie)即可靴庆。
當(dāng)用戶希望訪問一個受保護的路由或者資源的時候,通常應(yīng)該在Authorization頭部使用Bearer模式添加JWT怒医,其內(nèi)容看起來是下面這樣:
Authorization: Bearer <token>
因為用戶的狀態(tài)在服務(wù)端的內(nèi)存中是不存儲的炉抒,所以這是一種無狀態(tài)的認(rèn)證機制。服務(wù)端的保護路由將會檢查請求頭Authorization中的JWT信息稚叹,如果合法焰薄,則允許用戶的行為。由于JWT是自包含的扒袖,因此減少了需要查詢數(shù)據(jù)庫的需要塞茅。
JWT的這些特性使得我們可以完全依賴其無狀態(tài)的特性提供數(shù)據(jù)API服務(wù),甚至是創(chuàng)建一個下載流服務(wù)季率。因為JWT并不使用Cookie的野瘦,所以你可以使用任何域名提供你的API服務(wù)而不需要擔(dān)心跨域資源共享問題(CORS)。
3.JWT優(yōu)缺點
主要應(yīng)用場景
身份認(rèn)證
在這種場景下飒泻,一旦用戶完成了登陸鞭光,在接下來的每個請求中包含JWT,可以用來驗證用戶身份以及對路由泞遗,服務(wù)和資源的訪問權(quán)限進行驗證衰猛。由于它的開銷非常小,可以輕松的在不同域名的系統(tǒng)中傳遞刹孔,所有目前在單點登錄(SSO)中比較廣泛的使用了該技術(shù)啡省。
信息交換
在通信的雙方之間使用JWT對數(shù)據(jù)進行編碼是一種非常安全的方式,由于它的信息是經(jīng)過簽名的髓霞,可以確保發(fā)送者發(fā)送的信息是沒有經(jīng)過偽造的卦睹。
要保證私鑰的安全性,來保障簽名的安全方库。
有人提到j(luò)wt暴露簽名算法(alg)结序,而且會有None(無簽名),所以建議隱去alg纵潦。一般的協(xié)議制定都會考慮擴展性和普適性徐鹤。但是我們在應(yīng)用中可以采用我們默認(rèn)的算法垃环,而不是根據(jù)alg去處理。
不應(yīng)該在jwt的payload部分存放敏感信息返敬,因為該部分是客戶端可解密的部分遂庄。
4.解決方案
二、
參考文獻:
https://segmentfault.com/a/1190000005047525?utm_source=tuicool&utm_medium=referral
http://www.reibang.com/p/fcc1a6482143?from=timeline