Spring Cloud Alibaba 實戰(十一) - Spring Cloud認證授權

展開閱讀全文

本文主要內容:

  • 如何實現用戶認證與授權?
  • 實現的三種方案,全部是通過畫圖的方式講解.以及三種方案的對比
  • 最後根據方案改造Gateway和擴展Feign

0 相關源碼

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系列文章

代表實現

示例代碼

優劣分析

安全性好
但是實現成本高,而且多次token交換和認證,所以有性能開銷

2.2 外部無狀態,內部有狀態

  • 架構過於複雜,微服務和傳統架構混合雙搭

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 最流行)
  • 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
  • 引入工具類後生成的JWT,並新建JWT操作類,並簡單測試生成JWT
  • 寫配置
  • 同樣的方式爲內容中心添加JWT配置,不再贅述,注意secret都保持一致

5 實現認證授權

實現小程序登錄

  • 小程序登錄流程,我們java代碼需要做的就是實現圖中的4,5,6步驟
  • 用戶點擊登錄按鈕後,彈出如下,點擊允許,即表示同意獲取個人信息
  • login
  • 在用戶中心新建 dto類




服務實現

6 AOP實現登錄狀態檢查

實現方式

  • Servlet過濾器
  • filter攔截器
  • Spring AOP

我們當然使用優雅地AOP切面編程這種可插拔的方式

6.1 用戶中心

  • 引入依賴
  • 定義註解

具體代碼看github

6.2 內容中心

與用戶中心類似,不再贅述
使用feign時並沒有傳遞token,所以當做未認證處理

6.2.1 Feign實現Token傳遞

實現方式 @RequestHeader

  • 修改控制器,之後將編譯報錯的代碼都註釋掉

需要修改控制器,這不好,棄用

實現方式 RequestInterceptor

實現方式 RestTemplate實現Token傳遞

exchange()
ClientHttpRequestInterceptor

7 AOP實現用戶權限驗證 - 授權

  • 需求:用戶role須是管理員纔有權訪問

7.1 實現方案 - 土方法

  • 通過注入的屬性值判斷,對於API多的就不合時宜了!

當然你用過濾器,攔截器實現也是可以的.

7.2 優雅地用AOP實現

  • 定義註解
  • 控制器方法上添加註解


  • 修改網關配置

總結

◆ 登錄認證的四種方案
◆ AOP實現認證授權
◆ N種訪問控制模型
◆ Feign傳遞Token
◆ JWT
◆ RestTemplate傳遞Token

參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章