SpringBoot系列: Web應用鑒權思路


==============================
web 項目鑒權
==============================
主要的鑒權方式有:
1. 用戶名/密碼鑒權, 然后通過 Session/Cookie 保存鑒權結果.
2. 用戶名/密碼鑒權, 通過 Basic authentication 方式, 每次請求都要將 appId/appSecret 加到 HTTP [Authorization] header. 
3. 用戶名/密碼鑒權, 然后通過 JWT token 保存鑒權結果, 每次請求帶上jwt token, 加到 HTTP  X-Auth-Token header上.

JWT 的優點:
1. Jwt 是一個 stateless 方案, 不需要解決 session 共享問題.
2. Jwt 更適合於手機端的訪問, 因為移動端不支持 cookie.
3. Jwt 更適合於微服務端的驗證, 因為微服務的使用方通常不是web browser, 而是服務端程序, 使用 jwt 更方便.
3. Jwt 支持跨域訪問, 而 Cookie不允許.
4. Jwt 因為不依賴cookie, 所以不需要考慮CSRF(跨站請求偽造)攻擊.
JWT 的缺點:
1. 服務器端不能主動注銷 Jwt token, 使用 Session 方式時, 服務器端是能主動 logout 一個登陸.
2. 對於普通 Web 瀏覽器, 使用 cookie/Session 幾乎無感, 而 jwt 需要在請求的時候加 header.

Basic authentication 的優點:
1. 優點和Jwt差不多, 另外它比Jwt 更容易實現. 
basic authentication 的缺點:
1. 每次請求時都需要發送密碼, 所以僅僅適合於API項目的鑒權, 不適合WebUI 項目;
2. 和 jwt token 方式相比, 每次請求都需要受訪API服務驗證"密碼", 這往往要查詢DB, 而 jwt 只需要用算法即可 token 是否有效.

 

==============================
Web項目鑒權的推薦
==============================
(1) Web UI 項目, 建議采用 Session 來做權限驗證, Web UI 項目關注的是用戶級的權限.
(2) 純粹企業內部的 API 服務項目, 建議采用 Basic Auth 做權限驗證, 關注的是來源 app 是否有權限(粗粒度權限管控), 並不是每個登陸用戶的權限.
(3) 開放 API 平台, 建議采用 Jwt 做權限驗證, 關注的是來源 app 是否有權限(粗粒度權限管控), 並不是每個登陸用戶的權限.

不管是Session, 還是jwt token和basic authentication 方式, 至少都需要發送一次密碼, 如果是公網訪問的話, 應該走 https, 否則不管采用什么高級的框架, 都存在安全風險.
對於企業內部的API 服務項目, 通信都是發生在服務器之間, 可以不走 https, 為了防止 appId/appSecret 泄漏, 最好再結合 IP 白名單. 我猜測, 很多企業內部的API服務其實沒有任何鑒權, 完全是在裸奔.

 

==============================
Jwt Token 流程
============================== 

----------------------------
App Authentication 服務器
----------------------------
專門建有統一的 App Authentication 服務器, 集中管理 Access token 簽發, 可以將企業中的所有"微服務"都納入其管理, 統一管理, 有利用服務的治理.


----------------------------
Access token 的申請
----------------------------
一個 WebUI 應用或微服務如要訪問其他微服務, 需要向統一的 App Authentication 服務器申請 Access Token, 申請時提供自己的 appId/appSecret 和目標微服務 appId, 由 App Authentication 服務器負責決定是否簽發 access token, 在 token 中記錄申請 appId/目標 appId, 以及賦予的角色.

為了防止 appId 被冒用, 需要提早將 appId 和它所在的服務器 IP 加到 App Authentication 的白名單中.

為了防止 access token 被大量擴散, 針對同一個 appId 和目標 appId, 同時只能有兩個 Access Token, 之所以是兩個, 一方面可有效限制了 token 的數量, 另外能無縫覆蓋 token 失效期.

為了防止重復攻擊, 需要設定token有效期, 企業內部也不宜太短, 設置1~2天較好一些.

為了防止重復攻擊, 可以在token中帶上申請app 的白名單IP,  在驗證token的時候可以順帶驗證request 請求來源IP是否是白名單中. 

 

一個應用申請到 Access token 之后, 有責任先將該 token 保存, 最好保存到 DB 中, 另外最好有一個定時任務定期申請 access token, 並在 DB 中維護一個 token 池, 在用的時候應使用有效期更遠的那個 token.

----------------------------
Access token 的使用
----------------------------
在每次訪問微服務的時候, 都要在 headers 上加上 token 信息, 加到 X-Auth-Token 上.
在受訪微服務中, 驗證 access token 是否有效, 是否已經過期, 並提取出來源 app 的角色, 然后進行下一步權限上的管控.


==============================
術語解釋
==============================
JWT: 全稱 json web token, 包含 header 和 claims 和 signature 三個部分. 
   因為 token 中已經帶有 signature, 所以具有 token 自驗證機制, 能防止偽造.
   在 claim 中可以設定一個過期時間, 所以能防止 token 被人長期冒用.

Access token(基於 jwt):
   Access token: 對於開放平台, 一般通過 appId/appSecret 來獲取一個 access token, 比如微信就是這樣, 該 access token 有效期為 2 個小時, 調用微信公眾號的所有接口都需要帶上 access token.
在微信平台中, 重復獲取 Access token, 將導致之前獲取的 Access token 失效. 個人認為: 要在服務器端主動失效已經簽發的 token, 這將又走到了 session 的路子上, 這是一個 1+1<1 的做法, 也許只要控制每個 appId 同時能申請幾個 Access token 就行了, 比如限制 2 個有效 Access token.

 

Refresh token(基於 jwt)
微信是通過 appId/appSecret 來獲取 Refresh token, 有些平台是通過 Refresh token 來獲取 Access token, 所以 Refresh token 有效期比較長. 個人認為, 微信的做法更好一些, 一般情況下沒有必要再引入 Refresh token 這個概念.


==============================
參考
==============================
基於Token的WEB后台認證機制
http://www.cnblogs.com/xiekeli/p/5607107.html
使用JSON Web Token設計單點登錄系統
https://leon_lizi.gitbooks.io/json-web-token/content/chapter2.html#
聊一聊JWT與session
https://juejin.im/post/5a437441f265da43294e54c3
重拾后端之Spring Boot(四):使用JWT和Spring Security保護REST API
https://juejin.im/post/58c29e0b1b69e6006bce02f4


免責聲明!

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



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