本文主要内容:
- 如何實作使用者認證與授權?
- 實作的三種方案,全部是通過畫圖的方式講解.以及三種方案的對比
- 最後根據方案改造Gateway和擴充Feign
相關源碼
1 有狀态 vs 無狀态
1.1 有狀态

也可使用粘性會話,即:對相同IP的請求,NGINX總 會轉發到相同的Tomcat執行個體,這樣就就無需圖中的Session Store了。不過這種方式有很多缺點:比如使用者斷網重連,重新整理頁面,由于IP變了,NGINX會轉發到其他Tomcat執行個體,而其他執行個體沒有Session,于是就認為使用者未登入。這讓使用者莫名其妙。
粘性會話不是本章重點,如果感興趣可以百度一下(用得越來越少了)
1.2 無狀态
這裡講的是解密Token直接拿到使用者資訊;事實上要看項目的具體實作;有時候Token裡不一定帶有使用者資訊;而是利用Token某個地方查詢,才能獲得使用者資訊。
1.3 對比小結
2 微服務認證方案
2.1 “處處安全”
推薦閱讀
◆
OAuth2實作單點登入SSO OAuth 2.0系列文章代表實作
- Spring Cloud Security : https://cloud. spring.io/spring-cloud-security/reference/html/
- Jboss Keycloak : https://www.keycloak.org
示例代碼
- Spring Cloud Security認證授權示例代碼
- Keycloak認證授權示例代碼 (基于Servlet實作,無法和SpringCloudGateway整合)
優劣分析
安全性好
但是實作成本高,而且多次token交換和認證,是以有性能開銷
2.2 外部無狀态,内部有狀态
- 架構過于複雜,微服務和傳統架構混合雙搭
Spring Cloud Alibaba 實戰(十一) - Spring Cloud認證授權0 相關源碼 1 有狀态 vs 無狀态2 微服務認證方案3 通路控制模型(授權)4 JWT5 實作認證授權6 AOP實作登入狀态檢查7 AOP實作使用者權限驗證 - 授權總結參考
2.3 網關認證授權,内部裸奔
登入成功後,網關頒發token,之後使用者的每個請求都會攜帶該token,網關對其解密是否合法,過期等,token中會攜帶使用者資訊,是以網關還可解析token即可知道使用者是誰,比如解析出了id和name,就會将其加入請求的header中進行轉發,每個服務就知道是啥子使用者啦!
優劣
優點是實作簡單,性能佳,但是一旦網關的登入認證被攻破,就涼了
2.4 “内部裸奔”改進方案
請求經過網關到認證授權中心去登入,成功則頒發token,之後使用者請求都會攜帶該token,但是網關不對token做操作
這樣降低了網關的設計複雜度,網關不再關注使用者是誰了(不再解密解析token),隻負責轉發
讓系統也避免了裸奔的尴尬
但是要想解密token,還是需要密鑰,現在每個微服務都要去做解密工作,意味着每個服務都知道密鑰了.被洩露的風險随之增大,需要防止這種情況,可以定期更新密鑰,想辦法不讓開發直接看到密鑰本身(但是一般吧,除非有内部腦殘人士才會洩露密鑰,一般還是很安全的)
實作并不複雜,降低了網關的複雜度,但是密鑰如果洩露了,就完了,這個可以借助後面的方法避免,先留坑
2.5 方案對比與選擇
3 通路控制模型(授權)
- Access Control List (ACL)
- Role-based access control (RBAC 最流行)
Spring Cloud Alibaba 實戰(十一) - Spring Cloud認證授權0 相關源碼 1 有狀态 vs 無狀态2 微服務認證方案3 通路控制模型(授權)4 JWT5 實作認證授權6 AOP實作登入狀态檢查7 AOP實作使用者權限驗證 - 授權總結參考 - Attribute- based access control (ABAC)
- Rule-based access control
- Time-based access control
我們使用的token其實就是JWT,what's that?
4 JWT
4.1 定義
JWT全稱Json web token ,是一個開放标準(RFC 7519) ,用來在各方之間安全地傳輸資訊。JWT可被驗證和信任,因為它是數字簽名的。
4.2 組成
4.3 公式
token算法
-
Token = Base64(Header).Base64(Payload).Base64(Signature)
示例: aaaa.bbbbb.ccccc
簽名算法
◆ Signature = Header指定的簽名算法
(Base64(header).Base64(payload), 秘鑰)
● 秘鑰: HS256("aaaa.bbbbb",秘鑰)
- JWT操作工具類分享
- 為使用者中心引入JWT
Spring Cloud Alibaba 實戰(十一) - Spring Cloud認證授權0 相關源碼 1 有狀态 vs 無狀态2 微服務認證方案3 通路控制模型(授權)4 JWT5 實作認證授權6 AOP實作登入狀态檢查7 AOP實作使用者權限驗證 - 授權總結參考 - 引入工具類後生成的JWT,并建立JWT操作類,并簡單測試生成JWT
Spring Cloud Alibaba 實戰(十一) - Spring Cloud認證授權0 相關源碼 1 有狀态 vs 無狀态2 微服務認證方案3 通路控制模型(授權)4 JWT5 實作認證授權6 AOP實作登入狀态檢查7 AOP實作使用者權限驗證 - 授權總結參考 - 寫配置
Spring Cloud Alibaba 實戰(十一) - Spring Cloud認證授權0 相關源碼 1 有狀态 vs 無狀态2 微服務認證方案3 通路控制模型(授權)4 JWT5 實作認證授權6 AOP實作登入狀态檢查7 AOP實作使用者權限驗證 - 授權總結參考 - 同樣的方式為内容中心添加JWT配置,不再贅述,注意secret都保持一緻
5 實作認證授權
實作小程式登入
- 小程式登入流程,我們java代碼需要做的就是實作圖中的4,5,6步驟
Spring Cloud Alibaba 實戰(十一) - Spring Cloud認證授權0 相關源碼 1 有狀态 vs 無狀态2 微服務認證方案3 通路控制模型(授權)4 JWT5 實作認證授權6 AOP實作登入狀态檢查7 AOP實作使用者權限驗證 - 授權總結參考 - 使用者點選登入按鈕後,彈出如下,點選允許,即表示同意擷取個人資訊
Spring Cloud Alibaba 實戰(十一) - Spring Cloud認證授權0 相關源碼 1 有狀态 vs 無狀态2 微服務認證方案3 通路控制模型(授權)4 JWT5 實作認證授權6 AOP實作登入狀态檢查7 AOP實作使用者權限驗證 - 授權總結參考 - login
Spring Cloud Alibaba 實戰(十一) - Spring Cloud認證授權0 相關源碼 1 有狀态 vs 無狀态2 微服務認證方案3 通路控制模型(授權)4 JWT5 實作認證授權6 AOP實作登入狀态檢查7 AOP實作使用者權限驗證 - 授權總結參考 - 在使用者中心建立 dto類
Spring Cloud Alibaba 實戰(十一) - Spring Cloud認證授權0 相關源碼 1 有狀态 vs 無狀态2 微服務認證方案3 通路控制模型(授權)4 JWT5 實作認證授權6 AOP實作登入狀态檢查7 AOP實作使用者權限驗證 - 授權總結參考
-
小程式API工具包
◆WxJava :
https://github.com/Wechat-Group/WxJava - 在使用者中心添加依賴
Spring Cloud Alibaba 實戰(十一) - Spring Cloud認證授權0 相關源碼 1 有狀态 vs 無狀态2 微服務認證方案3 通路控制模型(授權)4 JWT5 實作認證授權6 AOP實作登入狀态檢查7 AOP實作使用者權限驗證 - 授權總結參考
服務實作
6 AOP實作登入狀态檢查
實作方式
- Servlet過濾器
- filter攔截器
- Spring AOP
我們當然使用優雅地AOP切面程式設計這種可插拔的方式
6.1 使用者中心
- 引入依賴
Spring Cloud Alibaba 實戰(十一) - Spring Cloud認證授權0 相關源碼 1 有狀态 vs 無狀态2 微服務認證方案3 通路控制模型(授權)4 JWT5 實作認證授權6 AOP實作登入狀态檢查7 AOP實作使用者權限驗證 - 授權總結參考 - 定義注解
Spring Cloud Alibaba 實戰(十一) - Spring Cloud認證授權0 相關源碼 1 有狀态 vs 無狀态2 微服務認證方案3 通路控制模型(授權)4 JWT5 實作認證授權6 AOP實作登入狀态檢查7 AOP實作使用者權限驗證 - 授權總結參考
具體代碼看github
6.2 内容中心
與使用者中心類似,不再贅述
使用feign時并沒有傳遞token,是以當做未認證處理
6.2.1 Feign實作Token傳遞
實作方式 @RequestHeader
- 修改控制器,之後将編譯報錯的代碼都注釋掉
Spring Cloud Alibaba 實戰(十一) - Spring Cloud認證授權0 相關源碼 1 有狀态 vs 無狀态2 微服務認證方案3 通路控制模型(授權)4 JWT5 實作認證授權6 AOP實作登入狀态檢查7 AOP實作使用者權限驗證 - 授權總結參考
需要修改控制器,這不好,棄用
實作方式 RequestInterceptor
實作方式 RestTemplate實作Token傳遞
exchange()
ClientHttpRequestInterceptor
7 AOP實作使用者權限驗證 - 授權
- 需求:使用者role須是管理者才有權通路
Spring Cloud Alibaba 實戰(十一) - Spring Cloud認證授權0 相關源碼 1 有狀态 vs 無狀态2 微服務認證方案3 通路控制模型(授權)4 JWT5 實作認證授權6 AOP實作登入狀态檢查7 AOP實作使用者權限驗證 - 授權總結參考
7.1 實作方案 - 土方法
- 通過注入的屬性值判斷,對于API多的就不合時宜了!
Spring Cloud Alibaba 實戰(十一) - Spring Cloud認證授權0 相關源碼 1 有狀态 vs 無狀态2 微服務認證方案3 通路控制模型(授權)4 JWT5 實作認證授權6 AOP實作登入狀态檢查7 AOP實作使用者權限驗證 - 授權總結參考
當然你用過濾器,攔截器實作也是可以的.
7.2 優雅地用AOP實作
-
Spring Cloud Alibaba 實戰(十一) - Spring Cloud認證授權0 相關源碼 1 有狀态 vs 無狀态2 微服務認證方案3 通路控制模型(授權)4 JWT5 實作認證授權6 AOP實作登入狀态檢查7 AOP實作使用者權限驗證 - 授權總結參考 - 控制器方法上添加注解
Spring Cloud Alibaba 實戰(十一) - Spring Cloud認證授權0 相關源碼 1 有狀态 vs 無狀态2 微服務認證方案3 通路控制模型(授權)4 JWT5 實作認證授權6 AOP實作登入狀态檢查7 AOP實作使用者權限驗證 - 授權總結參考
- 修改網關配置
Spring Cloud Alibaba 實戰(十一) - Spring Cloud認證授權0 相關源碼 1 有狀态 vs 無狀态2 微服務認證方案3 通路控制模型(授權)4 JWT5 實作認證授權6 AOP實作登入狀态檢查7 AOP實作使用者權限驗證 - 授權總結參考
總結
◆ 登入認證的四種方案
◆ AOP實作認證授權
◆ N種通路控制模型
◆ Feign傳遞Token
◆ JWT
◆ RestTemplate傳遞Token