導讀
當企業的應用系統逐漸增多后,每個系統單獨管理各自的用戶數據容易形成信息孤島,分散的用戶管理模式阻礙了企業應用向平台化演進。當企業的業務發展到一定規模,構建統一的標准化賬戶管理體系將是必不可少的,因為它是企業雲平台的重要基礎設施,能夠為平台帶來統一的帳號管理、身份認證、用戶授權等基礎能力,為企業帶來諸如跨系統單點登錄、第三方授權登錄等基礎能力,為構建開放平台和業務生態提供了必要條件。
背景
公司原有的各個業務系統都是通過域賬戶來打通的,隨着公司平台化、開放戰略的推進,公司對外提供的服務必須具備對外集成與被集成的能力,在這種需求下,單純的內部賬戶打通已顯然不能滿足需求,提供統一的賬戶管理、身份認證與授權勢在必行。
以我們的DevOps平台研發協同平台為例,平台要面向ISV合作伙伴開放, 首先面臨的就是賬戶問題,不單單是研發協同平台自身要向ISV合作提供服務,圍繞研發協同平台的其他服務(例如Jira, Confluence, Jenkins, Sonar)也要面向ISV合作伙伴提供服務,這就要求面向ISV合作伙伴必須提供統一的賬戶體系。
需求
統一身份管理
統一身份管理是整個平台帳號和權限管控的基礎,平台下所有系統的賬戶管理、身份認證、資源授權等行為都經由系統統一處理,提供帳號密碼管理、基本資料管理、資源管理、授權管理、客戶端管理等功能。統一身份管理基於統一身份治理的概念,可划分為賬戶體系、基礎信息、資源授權三大模塊。
其中賬戶體系將賬戶分為組織實體帳號和個人實體賬戶兩大類,個人實體從屬於組織實體,也可以不從屬任何組織實體,且個人實體可同時從屬於多個組織實體;基礎信息模塊用於描述組織實體和個人實體的基本信息,如組織實體名稱、地址、法人,個人實體姓名、電話號碼、性別等基礎信息;資源授權模塊將需要對外提供服務的業務服務資源進行統一管理和授權。
組織實體
在統一認證身份服務中,組織機構應當是一種實體,與之對應的另一種實體是個人實體(業務上是實體概念,和賬戶是有區別的)。因此要設計一種用於組織實體登入系統的方法,這里有兩種可選方案:一是增加組織實體賬戶,組織實體自身擁有賬戶,可直接進行認證登錄;二是將從屬於組織實體的個人賬戶作為組織實體的登入憑證。無論何種方法,在認證和授權時,都由統一身份認證服務提供統一標准的賬戶憑證,因此,組織實體的認證授權與個人實體的認證授權並無二致
單點登錄(SSO)
企業平台涉及眾多子系統,為簡化各子系統的用戶管理,提升用戶體驗,因此實現 SSO 是統一身份認證的重要目標:一次登錄,全部訪問。對於企業內部應用來說,SSO 是必須的選項,例如企業 OA、HR、CRM 等內部系統;對於外部應用來說,SSO 是可選項,具體哪個應用應當加入 SSO 系統,由該業務系統決定。無論何種應用服務是否采用 SSO,統一身份認證服務在技術上應當具備 SSO 的能力。
授權登錄
隨着平台業務的逐漸增長,依托於平台的,和平台依托的廠商和客戶等資源將極大的豐富平台,因此必須構築開放的生態系統,以支撐業務的進一步發展。必須開放平台級的授權登錄功能,以允許第三方應用接入。
資源授權
企業業務服務除了要集成第三方服務來提升服務能力,也需要對外提供服務,提供被集成的能力,這樣才能和第三方一起構建生態合作伙伴關系,實現共贏。因此,統一身份認證服務除了要提供認證,還需要提供服務資源授權的能力,以授權第三方集成企業提供的業務服務,將企業的業務服務開放給第三方,實現共同發展。
技術方案
IdentityServer4是基於ASP.NET Core的OpenID Connect和OAuth 2.0框架。它提供了以下豐富的功能:
身份驗證即服務
適用於所有應用程序(Web,本機,移動設備,服務)的集中登錄邏輯和工作流程。IdentityServer是OpenID Connect 的官方認證實現。
單點登錄/注銷
在多種應用程序類型上單點登錄(和退出)。
API訪問控制
為各種類型的客戶端發出API訪問令牌,例如服務器到服務器,Web應用程序,SPA和本機/移動應用程序。
聯合網關
支持Azure Active Directory,Google,Facebook等外部身份提供商。這可以保護您的應用程序免受如何連接到這些外部提供商的詳細信息的影響。
可定制
最重要的部分 - IdentityServer的許多方面都可以根據您的需求進行定制。由於IdentityServer是一個框架而不是盒裝產品或SaaS,因此您可以編寫代碼以使系統適應您的方案。
成熟的開源
IdentityServer使用允許的Apache 2許可證,允許在其上構建商業產品。它也是.NET Foundation的一部分,它提供治理和法律支持。
OAuth2.0 && OpenId Connect
IdentityServer4是基於ASP.NET Core的OpenID Connect和OAuth 2.0框架,我們先來了解OpenId Connect和OAuth 2.0的基本概念
OpenId
OpenID 是一個以用戶為中心的數字身份識別框架,它具有開放、分散性。OpenID 的創建基於這樣一個概念:我們可以通過 URI (又叫 URL 或網站地址)來認證一個網站的唯一身份,同理,我們也可以通過這種方式來作為用戶的身份認證。
簡而言之:OpenId用於身份認證(Authentication)
OAuth 2.0
OAuth(開放授權)是一個開放標准,目前的版本是2.0。允許用戶授權第三方移動應用訪問他們存儲在其他服務商上存儲的私密的資源(如照片,視頻,聯系人列表),而無需將用戶名和密碼提供給第三方應用。
OAuth允許用戶提供一個令牌而不是用戶名和密碼來訪問他們存放在特定服務商上的數據。每一個令牌授權一個特定的網站內訪問特定的資源(例如僅僅是某一相冊中的視頻)。這樣,OAuth可以允許用戶授權第三方網站訪問他們存儲在另外服務提供者的某些特定信息,而非所有內容。
OAuth是OpenID的一個補充,但是完全不同的服務。
簡而言之:OAuth2.0 用於授權(Authorization)
OpenId Connect
OpenID Connect 1.0 是基於OAuth 2.0協議之上的簡單身份層,它允許客戶端根據授權服務器的認證結果最終確認終端用戶的身份,以及獲取基本的用戶信息;它支持包括Web、移動、JavaScript在內的所有客戶端類型去請求和接收終端用戶信息和身份認證會話信息;它是可擴展的協議,允許你使用某些可選功能,如身份數據加密、OpenID提供商發現、會話管理等。
簡而言之:OpenId Connect = OIDC = Authentication + Authorization + OAuth2.0
術語
了解完OpenId Connect和OAuth2.0的基本概念,我們再來梳理下涉及到的相關術語:
Identity Server
認證授權服務器,是OpenID Connect提供程序, 它實現了OpenID Connect和OAuth 2.0協議。主要包括以下功能:
- 保護資源
- 使用本地帳戶存儲或外部身份提供程序對用戶進行身份驗證
- 提供會話管理和單點登錄
- 管理和驗證客戶端
- 向客戶發放身份和訪問令牌
- 驗證令牌
用戶(Users
用戶是使用注冊客戶端訪問資源的人
客戶端(Client)
客戶端是從IdentityServer請求令牌的應用 - 用於驗證用戶(請求身份令牌)或訪問資源(請求訪問令牌)。客戶端必須首先向IdentityServer注冊,然后才能請求令牌。常見的客戶端包括Web應用程序,本機移動或桌面應用程序,SPA,服務器進程等。
資源(Resources)
使用IdentityServer保護的資源 - 用戶的身份數據或服務資源(API)。每個資源都有一個唯一的名稱 - 客戶端使用此名稱來指定他們希望訪問哪些資源。身份數據 - 關於用戶的身份信息(也稱為聲明),例如姓名或電子郵件地址等。服務資源(API) - 表示客戶端要調用的服務 - 通常為Web API,但不一定。
令牌(Token)
令牌有身份令牌(Identity Token)和訪問令牌(Access Token)。身份令牌表示身份驗證的結果。它至少包含用戶標識以及有關用戶如何以及何時進行身份驗證的信息,還可以包含其他身份數據。訪問令牌允許訪問API資源,客戶端請求訪問令牌並將其轉發給API。訪問令牌包含有關客戶端和用戶(如果存在)的信息,API使用該信息來授權訪問其資源。
JWT認證
HTTP身份驗證流程
HTTP提供了一套標准的身份驗證框架:服務器可以用來針對客戶端的請求發送質詢(challenge),客戶端根據質詢提供身份驗證憑證。質詢與應答的工作流程如下:服務器端向客戶端返回401(Unauthorized,未授權)狀態碼,並在WWW-Authenticate頭中添加如何進行驗證的信息,其中至少包含有一種質詢方式。然后客戶端可以在請求中添加Authorization頭進行驗證,其Value為身份驗證的憑證信息。
Bearer認證(也叫做令牌認證)是一種HTTP認證方案,其中包含的安全令牌的叫做Bearer Token。因此Bearer認證的核心是Token。那如何確保Token的安全是重中之重。一種方式是使用Https,另一種方式就是對Token進行加密簽名。而JWT就是一種比較流行的Token編碼方式。
JWT(Json Web Token)
Json web token (JWT), 是為了在網絡應用環境間傳遞聲明而執行的一種基於JSON的開放標准。該token被設計為緊湊且安全的,特別適用於分布式站點的單點登錄(SSO)場景。JWT的聲明一般被用來在身份提供者和服務提供者間傳遞被認證的用戶身份信息,以便於從資源服務器獲取資源,也可以增加一些額外的其它業務邏輯所必須的聲明信息,該token也可直接被用於認證,也可被加密。
JWT有三部分組成:
<header>.<payload>.<signature>
Header - 由alg和typ組成,alg是algorithm的縮寫,typ是type的縮寫,指定token的類型。該部分使用Base64Url編碼。
Payload - 主要用來存儲信息,包含各種聲明,同樣該部分也由BaseURL編碼。
Signature - 簽名,使用服務器端的密鑰進行簽名。以確保Token未被篡改。
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
授權模式
IdentityServer4提供了以下幾種常見的授權模式:Client Credentials(客戶端憑證模式), Resource Owner Password Credentials(密碼模式), Implicit(簡化模式),Authorization Code, Device Flow(設備模式)
Client Credentials (客戶端憑證模式)
POST https://api.oauth2server.com/token grant_type=client_credentials& client_id=CLIENT_ID& client_secret=CLIENT_SECRET
客戶端憑證模式是最簡單的授權模式,因為授權的流程僅發生在Client與Identity Server之間。該模式的適用場景為服務器與服務器之間的通信。比如對於一個電子商務網站,將訂單和物流系統分拆為兩個服務分別部署。訂單系統需要訪問物流系統進行物流信息的跟蹤,物流系統需要訪問訂單系統的快遞單號信息進行物流信息的定時刷新。而這兩個系統之間服務的授權就可以通過這種模式來實現。
Resource Owner Password Credentials (密碼模式)
POST https://api.oauth2server.com/token grant_type=password& username=USERNAME& password=PASSWORD& client_id=CLIENT_ID
Resource Owner其實就是User,所以可以直譯為用戶名密碼模式。密碼模式相較於客戶端憑證模式,多了一個參與者,就是User。通過User的用戶名和密碼向Identity Server申請訪問令牌。這種模式下要求客戶端不得儲存密碼。但我們並不能確保客戶端是否儲存了密碼,所以該模式僅適用於受信任的客戶端。否則會發生密碼泄露的危險。該模式不推薦使用。
Implicit (簡化模式)
Implicit Flow 又稱為簡化流程,因為沒有任何后台服務參與使用 Authorization Grant 換取 Access Token 的流程,整個過程由 Browser 直接與 Authorization Server 通信。
Authorization Code
授權碼模式是一種混合模式,是目前功能最完整、流程最嚴密的授權模式。它主要分為兩大步驟:認證和授權。簡稱為 Code Flow,也是 OAuth 推崇的方案,該 Flow 同時采用了 Front Channel 和 Back Channel。它常見於 Web App 的場景。Client 應用程序通過 Front Channel 向 Authorization Server 申請 Authorization Code,再通過 Back Channel 用 Authorization Code 換取 Access Token。它假定 Resource Owner 和 Client 應用程序運行在不同的設備上,Access Token 始終不會傳輸到「用戶代理應用程序」
Device Flow
用於類似 TV 等硬件設備,或僅僅運行一個 Cli 的程序,直接與 Authorization Server 通信取得一個 code,再用 code 換取 Access Token 的流程。
身份認證服務實踐
在ASP.NET Core Wen API應用程序中配置和啟用Identity server中間件
- services.AddIdentityServer() - 配置identity server中間件
- AddInMemoryIdentityResources - 配置身份資源
- AddInMemoryApiResources - 配置API資源
- AddInMemoryClients - 配置客戶端
- AddTestUsers - 配置用戶
SonarQube集成身份認證服務授權登錄
-
使用管理員身份登錄SonarQube, 進入配置->通用設置->權限 設置OpenId Connect
-
設置完成,注銷賬戶,在登錄頁面選擇通過OpenId Connect登錄, 即可使用身份認證服務授權登錄SonarQube系統
寫在最后
在互聯網這個開放體系中,任務企業都可以集成第三方的服務來提升自己的服務能力,同時也可以將自己的服務能力開放給第三方提供被集成的能力,從而構建一個開放、共贏的生態體系。要開放、也要鏈接,而這繞不開的一個點就是認證授權問題。統一身份認證服務應運而生,各企業不再拘泥於內部的身份統一,在企業服務與企業服務之間建立安全可靠的鏈接,能夠加強信息的流通、服務能力的提升,促進企業生態的發展。