一、預備知識
本文討論基於微服務架構下的身份認證和用戶授權的技術方案,在閱讀之前,最好先熟悉並理解以下幾個知識點:
- 微服務架構相關概念:服務註冊、服務發現、API 網關
- 身份認證和用戶授權:SSO、CAS、OAuth2、JWT
文章在涉及到上述知識內容時,會附上參考鏈接。
二、背景
當企業的應用系統逐漸增多後,每個系統單獨管理各自的用戶數據容易行成信息孤島,分散的用戶管理模式阻礙了企業應用向平臺化演進。當企業的互聯網業務發展到一定規模,構建統一的標準化賬戶管理體系將是必不可少的,因爲它是企業互聯網雲平臺的重要基礎設施,能夠爲平臺帶來統一的帳號管理、身份認證、用戶授權等基礎能力,爲企業帶來諸如跨系統單點登錄、第三方授權登錄等基礎能力,爲構建開放平臺和業務生態提供了必要條件。
三、需求分析
在微服務架構下,必須對企業的平臺生態進行合理的業務劃分,每個業務板塊將自成系統,例如負責宣發的企業官網、主打文體的 B2B2C 商城、面向社區的物業服務系統等,這些系統業務比較獨立,應當獨立拆分。每個系統又可根據各自的業務模型進行切分,將業務模型和用戶需求統籌分析後建立恰當的領域模型,形成獨立的服務。
另外,企業平臺的客戶範圍比較複雜,有 2B 的業務,也有 2C 的,還有 2G(goverment)的,因此平臺級的統一身份管理必須涉及組織實體和個人實體兩類,其中組織實體包括政府機關(G)、企業單位(B)、團體組織(B)等,這類似於多租戶架構的概念,但又比傳統多租戶架構複雜。
一)統一身份管理(Unified Identity Manager)
統一身份管理(UIM)是整個平臺帳號和權限管控的基礎,由此構建的系統稱爲UIMS(Unified Identity Management System),平臺下所有系統的賬戶管理、身份認證、用戶授權、權限控制等行爲都經由 UIMS 處理,提供帳號密碼管理、基本資料管理、角色權限管理等功能。UIMS 基於『統一身份治理』的概念,可劃分爲兩級賬戶體系、基礎權限模塊和基礎信息模塊三大模塊。其中兩級賬戶體系將賬戶分爲組織實體帳號和個人實體賬戶兩大類,個人實體從屬於組織實體,也可以不從屬任何組織實體,且個人實體可同時從屬於多個組織實體;基礎權限模塊將各業務系統的資源權限進行統一管理和授權;基礎信息模塊用於描述組織實體和個人實體的基本信息,如組織實體名稱、地址、法人,個人實體姓名、電話號碼、性別等基礎信息。UIMS 提供統一的 API 與各子系統連接。
可以看到,衆多系統和衆多服務都將依賴於 UIMS 。本文僅涉及 UIMS 下的身份認證和用戶授權這兩塊,即兩級賬戶體系和基礎權限模塊,據此可以獨立出賬戶服務和鑑權服務,也可以合併成一個賬戶鑑權服務。
關於統一身份管理系統的介紹,請參考 https://mtide.net/平臺級SAAS架構的基礎-統一身份管理系統.html
二)軟件即服務(SAAS)
企業提供對外的 IT 服務,有兩種部署模式:一是私有云部署,二是公有化服務。公有云服務即 SAAS,提供系統級的應用服務,包括企業服務如企業郵箱、辦公 OA、人力資源系統等,個人服務如個人郵箱、雲筆記、雲網盤等。平臺級的 SAAS 應用架構,實際上是一種多租戶架構的升級版,加大了統一身份治理的難度。而基於 UIMS 系統的兩級賬戶體系,可以很容易做到這一點。值得注意的是,有些系統僅提供個人賬戶服務,有些系統僅提供組織賬戶服務,有的則兩者都提供,必須處理好個人實體和組織實體之間的關係。
關於 SAAS 的介紹,請參考 http://www.ruanyifeng.com/blog/2017/07/iaas-paas-saas.html
三)組織實體(Orginization Entity)
在 UIMS 中,組織機構應當是一種實體,與之對應的另一種實體是個人實體。注意實體(Entity)不是賬戶(Account),因此要設計一種用於組織實體登入受控系統的方法,這裏有兩種可選方案:一是增加組織實體賬戶,組織實體自身擁有賬戶,可直接進行認證登錄;二是將從屬於組織實體的個人賬戶作爲組織實體的登入憑證。無論何種方法,在認證和授權時,都應當向 UIMS 提供統一的標準的賬戶憑證,憑證的規格由 UIMS 定義,因此,組織實體的認證授權與個人實體的認證授權並無二致。
四)單點登錄(SSO)
企業平臺涉及衆多子系統,爲簡化各子系統的用戶管理,提升用戶體驗,因此實現 SSO 是統一身份認證的重要目標:一次登錄,全部訪問。對於企業內部應用來說,SSO 是必須的選項,例如企業 OA、HR、CRM 等內部系統;對於外部應用來說,SSO 是可選項,具體哪個應用應當加入 SSO 系統,由該業務系統決定,例如外部商城、物業系統等對外服務系統。無論何種應用是否採用 SSO,UIMS 在技術上應當具備 SSO 的能力。
關於SSO的介紹,請參考 https://www.cnblogs.com/EzrealLiu/p/5559255.html
五)授權登錄
隨着平臺業務的逐漸增長,依託於平臺的,和平臺依託的廠商和客戶等資源將極大的豐富平臺,因此必須構築開放的生態系統,以支撐業務的進一步發展。必須開放平臺級的授權登錄功能,以允許第三方應用接入。通過三方授權登錄,將平臺的服務各能力開發給第三方,並將第三方的服務和能力接入平臺,繁榮共生,共同發展。
六)服務間鑑權
業務系統切分出不同的服務,根據粒度粗細和業務需求不同,服務的數量和權限要求都不同。微服務架構下的身份認證和授權,可分爲兩種:
- 內部服務的認證和授權;
- 外部服務的認證和授權。
通常,內部服務處於安全的內網環境之下,例如鑑權服務、商品服務、訂單服務等,在對安全需求不高的情況下,可不執行認證過程,服務與服務之間是相互信任的。
而外部服務的認證和授權,通常由外部應用發起,通過反向代理或網關向安全邊界內的服務發起請求,因此必須執行嚴格的認證過程。無線端APP、Web端、桌面客戶端等外部應用下的各類服務,都屬於外部服務。
七)帳號登出和銷燬
與 SSO 相對應,UIMS 應該支持一次登出,全部登出,即 SSOff(Single Sign-Off,非標準術語);或者一次登出,部分登出,而是否全部登出或部分登出取決於用戶的選擇,例如用戶在 Web 端登出後,是否無線端 APP 也登出,這取決於用戶偏好,但系統應當提供這種能力。
此外,必須提供統一的銷燬功能,以支持用戶刪除其賬戶,一次銷燬,全部銷燬。
八)付費授權
雲平臺應具備付費授權機制,針對用戶賬戶和組織賬戶進行獨立授權。根據產品的商業策略,可執行靈活的付費模式:
- 時效限制:年付、季付、月付,不同時效費用不同;
- 功能限制:授權不同的功能,費用不同;
- 數量限制:最大組織數量限制、最大用戶數量限制,不同的數量費用不同。
四、技術方案
一)備選方案
上文基於『統一身份治理』的理念,提出了統一身份管理系統(UIMS)下關於身份認證和授權部分的主要需求。目前實現統一身份認證和授權的技術手段較多,總體可以歸納爲以下兩類:
- 傳統的 Cookie + Session 解決方案,有狀態會話模式;
- 基於令牌/票據的解決方案,無狀態交互模式。
具體有:
- 分佈式 Session
- OAuth2.0
- JWT
- CAS
上述方案各有利弊:
分佈式 Session 是老牌的成熟解決方案,但因其狀態化通信的特性與微服務提倡的API導向無狀態通信相互違背,且共享式存儲存在安全隱患,因此微服務一般不太採用。
OAuth2.0 是業內成熟的授權登錄解決方案,然而 OA2.0 提供了4種授權模式,能夠適應多種場景,作爲基於令牌的安全系統,可以廣泛用於需要統一身份認證和授權的場景。
關於 OAuth2.0 的介紹,請參考 http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html
- JWT(JSON Web Token)是一種簡潔的自包含的 JSON 聲明規範,因其分散存儲的特點而歸屬於客戶端授權模式,廣泛用於短期授權和單點登錄。由於 JWT 信息是經過簽名的,可以確保發送方的真實性,確保信息未經篡改和僞造。但由於其自包含的客戶端驗籤特性,令牌一經簽發,即無法撤銷,因此單純採用 JWT 作爲統一身份認證和授權方案無法滿足帳號統一登出和銷燬、帳號封禁和解除這幾種類型的需求。
關於 JWT 的介紹,請參考 http://blog.leapoahead.com/2015/09/06/understanding-jwt/
- CAS 是時下最成熟的開源單點登錄方案,包含 CAS Server 和 CAS Client 兩部分。CAS Server 是一個 war 包需要獨立部署,負責用戶認證;CAS Client 負責處理對客戶端受保護資源的訪問請求,需要認證時,重定向到 CAS Server。值得注意的是,CAS 是一個認證框架,其本身定義了一套靈活完整的認證流程,但其兼容主流的認證和授權協議如 OAuth2、SAML、OpenID 等,因此一般採用 CAS + OAuth2 的方案實現 SSO 和授權登錄。
關於 CAS 的介紹,請參考 https://apereo.github.io/cas/
在微服務架構下,身份認證和用戶授權通常分離出來成爲獨立的鑑權服務。在做技術選型時,應從以下幾點考慮:
- 滿足 SSO 的技術需求;
- 滿足簡便性和安全性的需求;
- 滿足開放性和擴展性的需求。
綜合考慮,推薦採用無狀態 API 模式,其中 OAuth2.0 能夠完全滿足。此外 JWT 除了不能滿足 SSOff 外,其他都能滿足,且是所有方案裏最爲簡便輕巧的一個,可通過搭配 API 網關來滿足 SSOff 特性的要求,因此 JWT + API 網關也是一個推薦的方案。
場景假設:構建基於圖像的物品識別系統(Image-Based Classification System)
爲便於理解統一認證和授權方案的細節,假定一種場景:團隊準備構建一套基於圖像的物品識別系統,允許用戶通過 H5 應用或 APP 上傳圖像,系統分析後返回識別結果;同時期望將此係統開放給社區和行業用戶以便商用;最後允許第三方應用將自身的功能接入 IBCS 以增強後者的能力。
下圖是該系統的微服務架構圖:
在微服務架構下,IBCS 分爲內外兩層,內層處於物理內網環境下,也稱爲內部服務,外層處於物理外網環境下,也稱爲外部服務,內外通過 API 網關連接。
- 內部服務:鑑權服務、配置服務、圖像識別服務屬於內部服務,通常內部服務之間是相互信任的,但在安全要求較高的場景下,內部服務也不能互信。
- 外部服務:桌面 APP、無線 APP、H5、第三方應用屬於外部服務,外部服務分爲兩種類型:一種是 IBCS 的一部分,如 APP、H5 這些前端應用;另一種是 IBCS 之外的第三方應用。兩種類型的授權方式是不一樣的,前者一般採用 OAuth2.0 的密碼模式,後者則採用客戶端模式。
下文將以物品識別系統爲例子,介紹這兩種推薦方案:
二)最佳方案: OAuth2.0
1. OAuth2.0 的四種授權模式
- 授權碼模式(authorization code)
- 簡化模式(implicit)
- 密碼模式(resource owner password credentials)
- 客戶端模式(client credentials)
其中密碼模式常用於外部服務的鑑權,客戶端模式常用於內部服務鑑權和開放平臺應用的授權,授權碼模式常用於社會化登錄和 SSO,因此 OAuth2.0 可作爲完整的統一身份認證和授權方案。
2. OAuth2.0 的幾種重要角色
必須注意的是,這些角色是相對的概念。
- 客戶端 Client:一般指第三方應用程序,例如用 QQ 登錄豆瓣網站,這裏的豆瓣網就是 Client;但在微服務體系裏,Client 通常是服務本身,如 APP 端的註冊登錄服務;
- 資源所有者 Resource Owner:一般指用戶,例如用 QQ 登錄豆瓣網站,這裏的所有者便是用戶;但在微服務體系裏,資源所有者是服務提供者本身;
- 資源服務器 Resource Server:一般指資源所有者授權存放用戶資源的服務器,例如用 QQ 登錄豆瓣網站,這裏的 QQ 就是資源服務器;但在微服務體系裏,服務提供者本身便是資源服務器;
- 授權服務器 Authorization Server:一般是指服務提供商的授權服務,例如用 QQ 登錄豆瓣網站,這裏的 QQ 便是授權服務器;類似地,在微服務體系裏,鑑權服務便是授權服務器。
3. IBCS 提供哪些功能
1)核心功能,以 API 形式暴露:
接口 | 描述 | body | 返回 | 權限 |
---|---|---|---|---|
POST /image-classify | 圖像識別 | { 圖片內容, token } | { 識別結果 } | 受控接口 |
2)由 UIMS 提供的功能:
功能/API | 描述 | body | 返回 | 權限 |
---|---|---|---|---|
POST /accounts/ | 註冊接口 | { username, password } | { sign-up-result } | 非受控接口 |
POST /accounts/login | 登錄接口 | { username, password } | { token } | 受控接口 |
POST /accounts/logout | 登出接口 | { token } | { logout-result } | 受控接口 |
SignUp-Page | 統一註冊頁面(UI) | 非受控頁面 | ||
Login-Page | 統一登錄頁面(UI) | 非受控頁面 |
其中,註冊接口、SignUp-Page 和 Login-Page 頁面是非受控接口/頁面,意味着無須鑑權即可訪問。
SignUp-Page 和 Login-Page 頁面是由 UIMS 提供的統一的註冊和登錄頁面,當外部服務發起註冊或登錄請求時,有兩種作法:一是統一跳轉到 UIMS 的註冊或登錄頁面,用戶完成操作後調用 UIMS 的註冊和登錄 API 完成請求;二是在自己的註冊和登錄頁面完成操作,然後以用戶名和密碼作爲參數調用 UIMS 的註冊和登錄 API 完成請求。推薦採用第一種方法,類似於全網通行證,用戶體驗統一,不用重複開發註冊登錄頁面。
3)成爲開發者,獲取 IBCS 的能力集:
- 第一步:申請成爲開發者。開發者分爲個人開發者和組織開發者兩類,實名認證也分兩種類型進行。成爲開發者的前提是成爲平臺的註冊用戶;
- 第二步:創建應用,平臺審覈通過後,生成 AppId 和 AppSecret 給到開發者,每個應用對應一對 AppId 和 AppSecret。值得注意的是,每個 AppID 與用戶賬號是綁定的,因此每個 AppId 獲取資源和能力的權限受到該用戶賬戶權限的限制,典型的例子是對象存儲服務(OSS/OBS);
- 第三步:獲取 Access Token,開發者按照 OAuth2.0 的規範,採用客戶端(client_credentials)模式,利用申請到的 AppId 和 AppSecret 向 IBCS 申請 token;
- 第三步:使用 Access Token 與平臺進行交互,每次調用受控 API 時都攜帶此 token。
4)成爲開發者,創建第三方應用:
一般來說,應當獨立建設一個開放平臺,開發平臺作爲整個雲平臺的一個子系統,同樣依賴於 UIMS。在開放平臺上,應當提供一套完善的界面和流程,以引導用戶完成開發者認證和第三方應用接入的所有工作。此外,在前期階段,也可以採用線下申請的方式,由管理員人工審覈,在後臺手動錄入。
在開放平臺上,創建第三方應用的流程和步驟,與上一步驟『成爲開發者,獲取 IBCS 的能力集』一致。所不同的是,上個步驟是獲取 IBCS 的能力,而本步驟『創建第三方應用』,是基於開放平臺開發應用,類似於微信小程序。
5)成爲開發者,將異構系統(第三方應用)接入 IBCS:
應該允許開發者將異構系統(第三方應用)接入 IBCS,以增強 IBCS 的能力。例如,假設 IBCS 本身不具備識別特種汽車的能力,但允許接入其他開發者開發的基於圖像的特種汽車識別應用。
第三方應用接入,歸屬於開放平臺的範疇。接入的流程和步驟,與第三步驟『成爲開發者,獲取 IBCS 的能力集』一致,由開放平臺提供標準的 API,第三方按照接入規範執行。
4. OAuth2.0 四種授權模式的應用場景
場景 | 描述 | 適用模式 |
---|---|---|
用戶註冊(外部服務) | 用戶在 APP 提供的註冊頁面,完成註冊請求 | 非受控接口,無須鑑權 |
用戶登錄(外部服務),返回 token | 用戶在 APP 提供的登錄頁面,完成登錄請求,獲得 token | 密碼模式(resource owner password credentials) |
用戶註冊(UIMS) | 用戶跳轉到 UIMS 的註冊頁面,完成註冊請求,註冊成功後,跳回到原服務 | 非受控接口,無須鑑權 |
用戶登錄(UIMS),返回 token | 用戶跳轉到 UIMS 的登錄頁面,完成登錄操作,獲得授權碼,然後攜帶授權碼跳轉到重定向URI,再獲得 token | 授權碼模式(authorization code) |
外部服務的鑑權 | 用戶在 APP 上使用圖像識別服務,APP 調用 IBCS 的圖像識別 API 並返回結果給用戶 | 密碼模式(resource owner password credentials) |
內部服務的鑑權 | 圖像識別服務向配置服務獲取配置信息 | 客戶端模式(client credentials),或簡單的 HTTP Basic 驗證 |
開發者:獲取 IBCS 能力集 | 客戶端模式(client credentials) | |
開發者:創建第三方應用 | 客戶端模式(client credentials) | |
開發者:接入第三方應用 | 客戶端模式(client credentials) |
5. 客戶端鑑權和用戶鑑權
服務鑑權,從形式上分爲:
- 非受控服務/接口,無須鑑權;
- 客戶端鑑權(服務自身鑑權):客戶端(服務)在訪問另一個服務時,必須先表明客戶端自己的身份;
- 業務鑑權(用戶鑑權):用戶通過客戶端(服務)訪問某個資源時,必須驗證用戶自己的身份。
例如,用戶通過 APP 登錄 IBCS 後,訪問圖像識別服務的過程:用戶登錄後獲得 token,由 APP 攜帶此 token 向圖像識別服務發起請求,圖像識別服務首先調用鑑權服務驗證 APP 的身份(通過 ClientId 和 ClientSecret),然後再驗證用戶的身份(通過 token),如果 APP 和用戶都獲得授權,則請求通過,返回識別結果。
6. 跨域問題
瀏覽器的同源策略給 Web 應用劃定了安全邊界,是 Web 應用安全模型的重要基礎。基於令牌的安全系統,在同源策略的約束下面臨兩個問題:
- 跨域請求;
- SSO 登錄狀態的跨域保持。
1)CORS 方案
第一個問題,一般採用 CORS 方案,在服務端的響應頭聲明 Access-Control-Allow-Origin 參數即可解決跨域請求的問題。
2)同域 SSO 方案
第二個問題,在同域環境下,傳統方法是採用 Cookie 的方案。跨域環境下,也有幾種方案,從安全性和簡便性考慮,推薦採用這種方案:
- 根據業務需求將應用切分爲同域 SSO 應用和跨域 SSO 應用兩類;
- 將需要 SSO 狀態保持的應用歸到同域 SSO 應用中,將其他應用歸到跨域 SSO 應用中;
- 對於同域 SSO 應用,一般是企業內部應用,或相關性較高的應用,這些應用的域名採用相同的父級域名,繼續使用 Cookie 方案;
- 對於跨域 SSO 應用,不提供 SSO 狀態保持。當用戶首次打開此類應用時,由於 Cookie 無法跨域,因此服務端無法感知用戶的登錄狀態,此時用戶是處於未登錄狀態的;當用戶訪問受控頁面或點擊登錄頁面時,須重新執行登錄操作。
7. 登出和關閉賬戶
OAuth2.0 是集中式的令牌安全系統,可以通過撤銷令牌登出系統。關閉賬戶與此類似。
8. 軟件授權
可在鑑權服務或 API 網關增加規則過濾器,將商業授權策略應用到授權規則中。
9. 技術選型
後續會寫實踐篇,敬請期待……
三)第二方案:JWT + API 網關
JWT 是一種自包含的客戶端令牌系統技術規範,這是其與 OAuth2.0 最大的不同。除此之外,可以簡單地將 JWT 當作 OAuth2.0 密碼模式的半自動版本。在實施 JWT 方案時,大部分情況下與 OAuth2.0 基本一致,本文不重複闡述,只對幾個要點和不同之處加以說明。
1. 搭配 API 網關實現令牌撤銷
由於 JWT 屬於自包含的客戶端令牌系統,令牌發出後無須服務器驗證,只需在客戶端驗證。客戶端驗證並解籤後將得到必要的信息,例如用戶基本信息和權限標識符。這種設計天然地存在無法撤銷令牌的問題。解決方案是在 API 網關對 JWT 進行攔截,這裏有多種方法:
- 令牌撤銷由 UIMS 發出,經由消息隊列、API 等手段通知到網關,網關維護一個已撤銷令牌的黑名單,對所有經過網關的 JWT 進行比對,TRUE 則拒絕轉發,並返回 401;
- 令牌撤銷由 UIMS 執行後,網關每次收到 JWT 請求時,查詢令牌數據庫(如 Redis),比對該令牌是否已經撤銷,如已撤銷則返回 401。
不過此方案仍然存在兩個問題:
- 將一定程度喪失 JWT 客戶端解籤的優勢,但相較於傳統的 Cookie + Session 方案,此方案更加輕巧,也更加符合微服務無狀態 API 的風格;
- 對於已發出的令牌,客戶端在下一次請求之前,服務端的令牌系統對此沒有控制能力,例如 SSOff 將無法很好地實現。
2. 客戶端鑑權和用戶鑑權
與 OAuth2.0 方案一致,客戶端同樣需要使用 ClientId 和 ClientSecret 鑑權。
3. 公鑰和密鑰
JWT 規定採用非對稱加密算法對 Header 和 Payload 進行簽名。
1)非對稱算法
非對稱算法的重要特點是,使用密鑰加密時,必須用公鑰解密;用公鑰加密時,必須用密鑰解密。利用此特性,通常在服務端採用密鑰加密信息,然後客戶端採用公鑰解密信息。由於密鑰存儲在服務端,因此安全性高;公鑰本身可以公開,因此可以在客戶端存儲。
2)公鑰解密
JWT 經由服務端用密鑰加密後,發往客戶端,客戶端使用公鑰進行解密,便得到了 JWT 的明文。JWT 包含了豐富的信息(通常是用戶基本信息和權限標識符),只要解密成功,客戶端完全可以信任此 JWT,因此不必再依賴於服務端重複鑑權。
4. 服務間鑑權
1)內部服務鑑權
以 IBCS 爲例,當圖像識別服務服務攜帶 JWT 向配置服務請求資源時,配置服務使用公鑰解密,只要解密成功,配置服務完全可以信任圖像識別服務,因此也不必再依賴於鑑權服務的重複鑑權。對於安全性要求不高的場景,也可以使用 HTTP Basic 驗證進行簡單鑑權。
2)外部服務鑑權
同樣,當外部的 APP 攜帶 JWT 向內網的圖像識別服務發起請求時,圖像識別服務使用公鑰解密,只要解密成功,圖像識別服務完全可以信任該 APP,有所不同的是,外部服務向內網服務發起請求,必須經過 API 網關,由網關執行規則過濾,確保 JWT 是仍處於有效狀態。
5. 跨域問題
與 OAuth2.0 的跨域解決方案一致。
五、總結
本文給出了微服務架構下的統一身份認證和授權的設計方案,從平臺級 SAAS 模式下『統一身份治理』的概念出發,梳理了關鍵的需求點,提出了對應的解決方案。其中 OAuth2.0 是最佳解決方案,不過在實際運用中,應當遵循『合適原則』、『簡單原則』和『演化原則』三個原則,不能盲目照搬。
六、參考鏈接
- SAAS,http://www.ruanyifeng.com/blog/2017/07/iaas-paas-saas.html
- SSO, https://www.cnblogs.com/EzrealLiu/p/5559255.html
- CAS, https://apereo.github.io/cas/
- UIMS, https://mtide.net/平臺級SAAS架構的基礎-統一身份管理系統.html