作者:半天
前言
API 作為企業的重要數字資源,在給企業帶來巨大便利的同時也帶來了新的安全問題,一旦被攻擊可能導致數據泄漏重大安全問題,從而給企業的業務發展帶來極大的安全風險。正是在這樣的背景下,OpenAPI 規范中針對 API 安全做了明確的定義和引導,以便用戶可以安全的管理自己的 API。以下為 OpenAPI 的定義:What is openAPI【1】
An OpenAPI file allows you to describe your entire API, including:
- Available endpoints (/users) and operations on each endpoint (GET /users, POST /users)
- Operation parameters Input and output for each operation
- Authentication methods
- Contact information, license, terms of use, and other information.
可以看到認證鑒權是保護 API 必要而又最常用的手段。云原生 API 網關(以下簡稱-網關)是云原生網關的升級版,除繼承了原云原生網關的全部能力,為用戶疊加了 API 管理的能力。云原生 API 網關是完全遵循 OpenAPI 規范的阿里云新一代 API 網關,支持豐富的認證鑒權是其核心競爭力之一。
什么是認證鑒權
認證:是指驗證用戶身份的過程。簡單來說,認證的目的是確認用戶是誰。在這個過程中,用戶通常需要提供某種憑證,例如用戶名和密碼、指紋、面部識別,或是其他生物特征,甚至是安全令牌(如兩步驗證中的驗證碼)。通過這些憑證,系統將用戶的身份與已有的身份信息進行比對,從而確認其真實性。
鑒權:是指驗證用戶是否有權限訪問某項資源或執行某項操作。雖然認證確認了用戶身份,但它并不能確定該用戶可以做什么。這方面的決策依賴于系統的權限管理策略。例如,在一個企業內部系統中,某位員工可能擁有訪問某些文件的權限,但另一些敏感文件則可能只對高級管理層開放。鑒權的目的就是在用戶經過認證后,根據其角色和權限設置,決定是否允許其訪問特定資源或執行特定操作。
認證(Authentication)
Key 認證
云原生 API 網關中的 Key 認證叫 API Key 認證在消費者鑒權中統一透出。Key 認證是對用戶密碼認證方式的方式的優化版本,通過靜態秘鑰的方式,為用戶提供了一種簡便快捷且安全的認證方式,具有較為鮮明的優缺點:
優點:
1、簡單易用,只需要在請求中傳輸秘鑰即可,驗證非常簡單、性能高
2、認證過程無需用戶參與,對自動化應用非常友好
3、服務器(網關)可以隨時生成、汰換(刪除)、重置(切換)秘鑰,管理方便
缺點:
1、安全隱患,秘鑰傳輸過程中很容易泄漏,泄漏后任何人都可以使用秘鑰來偽裝合法身份,進行未授權的操作;秘鑰的分配和管理復雜
2、無法提供用戶身份,審計較為困難
Api Key 認證的基本流程
云原生 API 網關的通過消費者授權來支持 API Key 認證,用戶在消費者創建流程中,選擇 API Key 身份認證,并且為其設置憑證來源和添加憑證。
云原生網關支持三種憑證來源設置方式:來源于固定 Header 頭"Authorization"、來源于自定義 Header 頭、以及來源自定義 QueryString。
curl??http://xxx.hello.com/test?apikey=2bda943c-ba2b-11ec-ba07-00163e1250b5
curl??http://xxx.hello.com/test?-H?'x-api-key:?2bda943c-ba2b-11ec-ba07-00163e1250b5'
JWT 認證
什么是 JWT
JWT(JSON Web Token)是一種用于安全信息傳遞的開放標準,它允許在通信雙方之間以 JSON 對象的形式傳輸安全信息,它設計為其中的信息可以被驗證和信任。
JWT 通常由三部分組成:頭部(Header)、載荷(Payload)和簽名(Signature),其內容構造過程如下:
1. 頭部(Header):
通常由兩部分組成:令牌的類型(通常是 JWT)和所使用的簽名算法(如 HMAC SHA256,在下文 JWKS 中指定);
{"alg": "HS256","typ": "JWT"
}
然后將頭部進行 Base64 編碼(該編碼是可以對稱解碼的),得到第一部分:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
2. 載荷(Payload):
包含對 JWT 的聲明(Claims),這些聲明是關于實體(通常是用戶)和其他數據的。定義細節如下:
iss:令牌頒發者。表示該令牌由誰創建,該聲明是一個字符串
sub: Subject Identifier,iss提供的終端用戶的標識,在iss范圍內唯一,最長為255個ASCII個字符,區分大小寫
aud:Audience(s),令牌的受眾,分大小寫的字符串數組
exp:Expiration time,令牌的過期時間戳。超過此時間的token會作廢, 該聲明是一個整數,是1970年1月1日以來的秒數
iat: 令牌的頒發時間,該聲明是一個整數,是1970年1月1日以來的秒數
jti: 令牌的唯一標識,該聲明的值在令牌頒發者創建的每一個令牌中都是唯一的,為了防止沖突,它通常是一個密碼學隨機值。這個值相當于向結構化令牌中加入了一個攻擊者無法獲得的隨機熵組件,有利于防止令牌猜測攻擊和重放攻擊。
也可以新增用戶系統需要使用的自定義字段,比如下面的例子添加了name 用戶昵稱:
{"sub": "1234567890","name": "John Doe"
}
然后將其進行 Base64 編碼,得到 JWT 的第二部分:
JTdCJTBBJTIwJTIwJTIyc3ViJTIyJTNBJTIwJTIyMTIzNDU2Nzg5MCUyMiUyQyUwQSUyMCUyMCUyMm5hbWUlMjIlM0ElMjAlMjJKb2huJTIwRG9lJTIyJTBBJTdE
3. 簽名(Signature):
為了生成簽名部分,需要將編碼后的頭部、載荷和一個密鑰(有些情況下是私鑰)按照指定的算法(在下文 JWKS 中指定)組合在一起進行簽名。
這個部分需要 Base64 編碼后的 Header 和 Base64 編碼后的 Payload 使用 . 連接組成的字符串,然后通過 Header 中聲明的加密方式進行加密($secret 表示用戶的私鑰),然后就構成了 JWT 的第三部分。
var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);
var signature = HMACSHA256(encodedString, '$secret');
將這三部分用 . 連接成一個完整的字符串,eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.JTdCJTBBJTIwJTIwJTIyc3ViJTIyJTNBJTIwJTIyMTIzNDU2Nzg5MCUyMiUyQyUwQSUyMCUyMCUyMm5hbWUlMjIlM0ElMjAlMjJKb2huJTIwRG9lJTIyJTBBJTdE.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
什么是 JWKS
在云原生 API 網關中,通過一組 JWKS 來描述 Header 信息,JWKS(JSON Web Key Set)是一種用于表示公鑰和私鑰集合的格式,通常用于支持 JWT 的身份驗證和授權場景。
{"keys": [{"kty": "oct","k": "GFmQpiJq42SxAWyIN5vnlUzrVDhcdBjKZ8uw0ag3XO1","alg": "HS256"}]
}
{"keys": [{"e": "公鑰的指數,例如AQAB","kid": "Key ID","kty": "使用的加密算法的家族,例如RSA,必填,大小寫敏感","alg": "使用的具體的加密算法,例如RS256,必填,大小寫敏感","use": "密鑰的用途,例如sig,用于簽名","n": "公鑰的模值"}]
}
JWT 認證是云原生 API 網關消費者認證能力中的一種,其認證流程如下:
- 客戶端向 API 網關發起認證請求,請求中一般會攜帶終端用戶的用戶名和密碼。
- 網關將請求直接轉發給后端服務。
- 后端服務讀取請求中的驗證信息(比如用戶名、密碼)進行驗證,驗證通過后使用私鑰生成標準的 token,返回給網關。
- 網關將攜帶 token 的應答返回給客戶端,客戶端需要將這個 token 緩存到本地。
- 客戶端向 API 網關發送業務請求,請求中攜帶 token。
- 網關使用用戶通過 JWT 認證配置中 JWKS 設定的公鑰對請求中的 token 進行驗證,驗證通過后,將請求透傳給后端服務。
- 后端服務進行業務處理后應答。
- 網關將業務應答返回給客戶端。
注意事項:
- JWT 通常設置有過期時間,過期時間的設置是一次性的,即客戶端需要合理的管理 Token 的失效以免 Token 失效后影響訪問,同時 Token 一旦頒發無法撤銷,即使用戶已經無權限,只要 Token 還在有效期,便依然可以訪問,引發安全風險。
- JWT 默認是不加密,不要將秘密數據寫入 JWT。
- JWT 本身包含了認證信息,一旦泄露,任何人都可以獲得該令牌的所有權限。為了減少盜用,JWT 的有效期應該設置得比較短。對于一些比較重要的權限,使用時應該再次對用戶進行認證。
- 為了減少盜用,JWT 不應該使用 HTTP 協議明碼傳輸,要使用 HTTPS 協議傳輸。
AK/SK 認證
AK(Access Key ID)/SK(Access Secret Key): 是阿里云對一個明確的用戶身份的一個抽象,云原生API網關沿用這個設計(注意:這里的云原生 API 網關生成的 AK/SK 與 RAM 的 AK /SK 相互獨立,并不能互通使用),用來標識一個網關用戶的身份,因為每個用戶可能有多種身份類型,每種身份類型可以有多個憑證,類似多個賬號,一組 AK/SK 可以簡單對應到一組用戶賬密。
API 提供者給有權限的用戶分配 AK/SK,API 消費者請求時帶上 AK,服務端就可以識別調用者的信息,并進行更細粒度的權限管理。
HMAC: HMAC(Hash-based Message Authentication Code)是一種基于哈希函數的消息認證碼,用于驗證信息的完整性和身份驗證。HMAC 結合了哈希函數和密鑰的優點,提供了數據的完整性和安全認證的保證。
在基于 HMAC 的 AK/SK 認證過程中,HMAC 的主要作用是確保消息的完整性和身份驗證。其具體作用如下:
- 身份驗證: 通過使用共享密鑰,只有持有該密鑰的用戶才能生成正確的 HMAC,從而可以確認消息的發送者的身份。
- 數據完整性: 任何對消息內容的修改都會導致 HMAC 值的變化,因此接收方可以通過計算接收到的消息的 HMAC 值來驗證消息在傳輸過程中是否被篡改。
- 防止重放攻擊: 在某些情況下,HMAC 還可以幫助防止重放攻擊。通過在消息中加入時間戳或隨機數,接收方可以確保消息的唯一性和新鮮性。
AK/SK(HMAC)認證是云原生 API 網關消費者認證能力中的一種,其認證流程包括客戶端生成簽名和服務端驗證前面兩個步驟。
客戶端生成簽名流程:
- 提取簽名串:客戶端從 HTTP 請求中提取出關鍵數據,組成一個簽名串,如云原生 API 網關的簽名串內容主要由以下 7 部分組成:
HTTPMethod
Accept
Content-MD5
Content-Type
Date
Headers
PathAndParameters
POST /http2test/test?param1=test HTTP/1.1
host:api.aliyun.com
accept:application/json; charset=utf-8
ca_version:1
content-type:application/x-www-form-urlencoded; charset=utf-8
x-ca-timestamp:1525872629832
date:Wed, 09 May 2018 13:30:29 GMT+00:00
user-agent:ALIYUN-ANDROID-DEMO
x-ca-nonce:c9f15cbf-f4ac-4a6c-b54d-f51abf4b5b44
content-length:33
username=xiaoming&password=123456789
提取原簽名串并追加 AK/SK 認證的 AK 和簽名算法,形成最終簽名串,header 之間用 \n 換行符分隔
POST
application/json; charset=utf-8
application/x-www-form-urlencoded; charset=utf-8
Wed, 09 May 2018 13:30:29 GMT+00:00
/http2test/test?param1=test&password=123456789&username=xiaoming
x-ca-nonce:c9f15cbf-f4ac-4a6c-b54d-f51abf4b5b44
x-ca-timestamp:1525872629832##添加AK/SK認證Headers
x-ca-key:203753385,AK/SK身份配置中的AK
x-ca-signature-method:HmacSHA256
- 加密簽名:對第1步提取的簽名串使用 HmacSha256 算法進行加密和 Base64 編碼處理得到簽名內容,如:
Mac hmacSha256 = Mac.getInstance("HmacSHA256");
byte[] secretBytes = secret.getBytes("UTF-8");
hmacSha256.init(new SecretKeySpec(secretBytes, 0, secretBytes.length, "HmacSHA256"));
byte[] result = hmacSha256.doFinal(stringToSign.getBytes("UTF-8"));
String sign = Base64.encodeBase64String(result);
- 添加簽名:將第 2 步生成的簽名和參與前面參與加簽的 header 作為 header 一并添加到 http 請求中:
x-ca-signature-headers:參與簽名的header的key的集合,英文逗號分隔
x-ca-signature:簽名,必選。
得到待發送給網關的攜帶簽名的 HTTP 請求:
POST /http2test/test?param1=test HTTP/1.1
host:api.aliyun.com
accept:application/json; charset=utf-8
ca_version:1
content-type:application/x-www-form-urlencoded; charset=utf-8
x-ca-timestamp:1525872629832
date:Wed, 09 May 2018 13:30:29 GMT+00:00
user-agent:ALIYUN-ANDROID-DEMO
x-ca-nonce:c9f15cbf-f4ac-4a6c-b54d-f51abf4b5b44
content-length:33
username=xiaoming&password=123456789##添加AK/SK認證Headers
x-ca-key:203753385
x-ca-signature-method:HmacSHA256##添加AK/SK認證Headers簽名相關的headers
x-ca-signature-headers:x-ca-timestamp,x-ca-key,x-ca-nonce,x-ca-signature-method
x-ca-signature:xfX+bZxY2yl7EB/qdoDy9v/uscw3Nnj1pgoU+Bm6xdM=
網關驗證簽名流程圖:
- 提取簽名串:從接收到的請求中提取關鍵數據,得到一個用來簽名的字符串。
收到的 HTTP 請求:
POST /http2test/test?param1=test HTTP/1.1
host:api.aliyun.com
accept:application/json; charset=utf-8
ca_version:1
content-type:application/x-www-form-urlencoded; charset=utf-8
x-ca-timestamp:1525872629832
date:Wed, 09 May 2018 13:30:29 GMT+00:00
user-agent:ALIYUN-ANDROID-DEMO
x-ca-nonce:c9f15cbf-f4ac-4a6c-b54d-f51abf4b5b44
content-length:33
username=xiaoming&password=123456789##AK/SK(HMAC)認證新增的header
x-ca-key:203753385
x-ca-signature-method:HmacSHA256##簽名新增的header
x-ca-signature-headers:x-ca-timestamp,x-ca-key,x-ca-nonce,x-ca-signature-method
x-ca-signature:xfX+bZxY2yl7EB/qdoDy9v/uscw3Nnj1pgoU+Bm6xdM=
-
提取 AK:從接收到的請求中讀取 AK ,通過 AK 查詢到對應的 SK。
-
提取簽名串并計算簽名:使用加密算法和 SK 對關鍵數據簽名串進行加密處理,得到簽名。
POST /http2test/test?param1=test HTTP/1.1
host:api.aliyun.com
accept:application/json; charset=utf-8
ca_version:1
content-type:application/x-www-form-urlencoded; charset=utf-8
x-ca-timestamp:1525872629832
date:Wed, 09 May 2018 13:30:29 GMT+00:00
user-agent:ALIYUN-ANDROID-DEMO
x-ca-nonce:c9f15cbf-f4ac-4a6c-b54d-f51abf4b5b44
content-length:33
username=xiaoming&password=123456789##AK/SK(HMAC)認證新增的header
x-ca-key:203753385
x-ca-signature-method:HmacSHA256
- 簽名驗證:從接收到的請求中讀取客戶端簽名,服務端使用第 3 不獲取的私鑰進行簽名驗證,對比服務器端簽名和客戶端簽名的一致性,從而判斷客戶是否認證通過。
OAuth2 認證
什么是 OAuth 2.0
OAuth 2.0 是一種用于授權的協議,廣泛用于互聯網應用以實現安全的授權機制。OAuth 2.0 定義以下幾種角色:
- 資源擁有者(Resource Owner): 通常是用戶,擁有數據訪問權限,以下簡稱為用戶
- 客戶端(Client): 請求訪問資源的應用程序。
- 授權服務器(Authorization Server): 負責驗證用戶并發放訪問令牌的服務器。
- 資源服務器(Resource Server): 存儲用戶數據的服務器。
OAuth 2.0 協議的流程主要包含以下幾個步驟:
1、客戶端請求用戶授權,此時通常會跳轉第三方登錄頁
2、資源擁有者用戶同意授權
3、客戶端使用已獲得授權,請求授權服務器發放Access Token
4、授權服務器返回Access Token
5、客戶端使用Access Token,請求資源服務器
6、資源服務器驗證Access Token,并返回受保護的資源
抽象流程圖
OAuth 2.0 協議定義了 4 種授權模式:
- 授權碼模式(authorization code)
- 簡化模式(implicit)
- 密碼模式(resource owner password credentials)
- 客戶端模式(client credentials)
**授權碼模式:
其中授權碼模式是最為廣泛使用的授權模式,它適用于用戶授予第三方客戶端訪問自身資源的場景,其核心流程如下:
用戶通過User-Agent(用戶代理,通常是瀏覽器)與Client第三方客戶端進行交互,其交互流程主要包含以下三步:
A、瀏覽器訪問客戶端應用程序
B、用戶通過瀏覽器與客戶端交互
C、客戶端通過瀏覽器透傳AuthorizationCode及RedirectUri等參數User-Agent代理用戶與授權服務器交互,其交互流程如下:
A、User-Agent使用第三方授權,User-Agent攜帶client定位符與重定向uri地址將用戶指向
認證服務器的認證頁
B、用戶通過User-Agent授權訪問
C、授權服務器進行認證鑒權,認證鑒權通過后將授權碼附在A步驟重定向Uri地址之后,然后導向重定向Uri
D、客戶端收到授權碼將其附在重定向uri中,請求授權服務器,獲取Access Token
E、授權服務器和核對重定向uri地址和授權碼無誤后,發放Access Token和Refresh Token(可選的)
授權碼授權流程圖:
客戶端模式:
客戶端模式是一種簡化的授權模式,它是客戶端以"Client"的名義請求資源服務器,而不是以"用戶"名義,它適用于受信的客戶端訪問。
OIDC 認證
OIDC 是 OpenID Connect 的簡稱。OIDC(OpenID Connect)是在 OAuth 2.0 之上構建的身份認證層,為應用程序提供用戶身份驗證的能力。
為什么要有OIDC
- 身份驗證和授權的分離: OAuth 2.0 主要關注授權 Authorization,而 OIDC 擴展了認證的抽象,任意完成身份認證的 Provider 實現,都能成為 Identity Provider,并作為 OpenID Provider 在 OIDC 協議中承擔認證的職責
- 用戶信息獲取: OIDC 在擴展認證的基礎提供了標準化的 API 來獲取用戶的基本信息,使得開發者能夠輕松集成用戶的個人信息。
總結一下:OAuth 2.0 設計之初是為了解決授權的問題,而 OIDC ?在 OAuth 2.0 的基礎上擴展了關于認證的定義并且添加一組獲取用戶信息的 API,且 OIDC 完全兼容 OAuth 2.0 協議。
OIDC 基于 OAuth 2.0 協議實現的角色及關鍵資源定義
OIDC 認證
通過云原生 API 網關的 OIDC 認證功能,可以實現在網關統一認證鑒權,并支持域名級別的黑白名單方便用戶靈活的管理認證授權的粒度,其核心流程如下:
OIDC 認證詳細流程
- 訪問用戶受保護的資源(需要認證授權訪問的 API)
curl --url "foo.bar.com/headers"
- 云原生 API 網關將請求重定向到身份提供商(IDP)登錄頁同時攜帶 client_id、response_type、scope 等 OIDC 認證的參數,response_type 設置為 code,即使用 OAuth 2.0 授權碼模式獲取 token,同時設置 csrf cookie, 防御 csrf 攻擊(Cross-Site Request Forgery -跨站請求偽造)
curl --url "https://dev-o43xb1mz7ya7ach4.us.auth0.com/authorize"\--url-query "approval_prompt=force" \--url-query "client_id=YagFqRD9tfNIaac5BamjhsSatjrAnsnZ" \--url-query "redirect_uri=http%3A%2F%2Ffoo.bar.com%2Foauth2%2Fcallback" \--url-query "response_type=code" \--url-query "scope=openid+email+offline_access" \--url-query "state=nT06xdCqn4IqemzBRV5hmO73U_hCjskrH_VupPqdcdw%3A%2Ffoo" \--header "Set-Cookie: _oauth2_proxy_csrf=LPruATEDgcdmelr8zScD_ObhsbP4zSzvcgmPlcNDcJpFJ0OvhxP2hFotsU-kZnYxd5KsIjzeIXGTOjf8TKcbTHbDIt-aQoZORXI_0id3qeY0Jt78223DPeJ1xBqa8VO0UiEOUFOR53FGxirJOdKFxaAvxDFb1Ok=|1718962455|V1QGWyjQ4hMNOQ4Jtf17HeQJdVqHdt5d65uraFduMIU=; Path=/; Expires=Fri, 21 Jun 2024 08:06:20 GMT; HttpOnly"
- 重定向到身份提供商(IDP)登錄頁(在云原生網關為用戶配置的認證服務提供的登錄頁)
-
用戶輸入用戶名密碼登錄完成,完成認證授權
-
攜帶授權碼重定向到云原生 API 網關并攜帶了 state 參數用于驗證 csrf cookie ,授權碼用于交換 token
curl --url "http://foo.bar.com/oauth2/callback" \--url-query "state=nT06xdCqn4IqemzBRV5hmO73U_hCjskrH_VupPqdcdw%3A%2Ffoo" \--url-query "code=0bdopoS2c2lx95u7iO0OH9kY1TvaEdJHo4lB6CT2_qVFm"
-
校驗 csrf cookie 中加密存儲的 state 值與 url 參數中的 state 值必須相同
-
利用授權碼,請求身份提供商(IDP)交換 id_token 和 access_token、refresh_token
curl -X POST \--url "https://dev-o43xb1mz7ya7ach4.us.auth0.com/oauth/token" \--data "grant_type=authorization_code" \--data "client_id=YagFqRD9tfNIaac5BamjhsSatjrAnsnZ" \--data "client_secret=ekqv5XoZuMFtYms1NszEqRx03qct6BPvGeJUeptNG4y09PrY16BKT9IWezTrrhJJ" \--data "redirect_uri=http%3A%2F%2Ffoo.bar.com%2Foauth2%2Fcallback" \--data "code=0bdopoS2c2lx95u7iO0OH9kY1TvaEdJHo4lB6CT2_qVFm" \
返回的請求里包含了 id_token, access_token,refresh_token 用于后續刷新 token
{"access_token": "eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIiwiaXNzIjoiaHR0cHM6Ly9kZXYtbzQzeGIxbXo3eWE3YWNoNC51cy5hdXRoMC5jb20vIn0..WP_WRVM-y3fM1sN4.fAQqtKoKZNG9Wj0OhtrMgtsjTJ2J72M2klDRd9SvUKGbiYsZNPmIl_qJUf81D3VIjD59o9xrOOJIzXTgsfFVA2x15g-jBlNh68N7dyhXu9237Tbplweu1jA25IZDSnjitQ3pbf7xJVIfPnWcrzl6uT8G1EP-omFcl6AQprV2FoKFMCGFCgeafuttppKe1a8mpJDj7AFLPs-344tT9mvCWmI4DuoLFh0PiqMMJBByoijRSxcSdXLPxZng84j8JVF7H6mFa-dj-icP-KLy6yvzEaRKz_uwBzQCzgYK434LIpqw_PRuN3ClEsenwRgIsNdVjvKcoAysfoZhmRy9BQaE0I7qTohSBFNX6A.mgGGeeWgugfXcUcsX4T5dQ","refresh_token": "GrZ1f2JvzjAZQzSXmyr1ScWbv8aMFBvzAXHBUSiILcDEG","id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Imc1Z1ExSF9ZbTY0WUlvVkQwSVpXTCJ9.eyJlbWFpbCI6IjE2MDExNTYyNjhAcXEuY29tIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJpc3MiOiJodHRwczovL2Rldi1vNDN4YjFtejd5YTdhY2g0LnVzLmF1dGgwLmNvbS8iLCJhdWQiOiJZYWdGcVJEOXRmTklhYWM1QmFtamhzU2F0anJBbnNuWiIsImlhdCI6MTcxOTE5ODYzOCwiZXhwIjoxNzE5MjM0NjM4LCJzdWIiOiJhdXRoMHw2NjVkNzFlNzRjMTMxMTc3YmU2NmU2MDciLCJzaWQiOiJjdDJVOF9ZUS16VDdFOGkwRTNNeUstejc5ZGlWUWhhVSJ9.gfzXKJ0FeqzYqOUDLQHWcUG19IOLqkpLN09xTmIat0umrlGV5VNSumgWH3XJmmwnhdb8AThH3Jf-7kbRJzu4rM-BbGbFTRBTzNHeUajFOFrIgld5VENQ_M_sXHkTp0psWKSr9vF24kmilCfSbvC5lBKjt878ljZ7-xteWuaUYOMUdcJb4DSv0-zjX01sonJxYamTlhji3M4TAW7VwhwqyZt8dBhVSNaRw1wUKj-M1JrBDLyx65sroZtSqVA0udIrqMHEbWYb2de7JjzlqG003HRMzwOm7OXgEd5ZVFqgmBLosgixOU5DJ4A26nlqK92Sp6VqDMRvA-3ym8W_m-wJ_A","scope": "openid email offline_access","expires_in": 86400,"token_type": "Bearer"
}
- 網關將獲得的 id_token, access_token, refresh_token 加密存儲在 cookie _oauth2_proxy 中
9.重定向到用戶訪問的后端服務并設置 cookie,用于后續用戶登錄狀態的驗證,同時清除 csrf 防護中設置的 cookie _oauth2_proxy_csrf
"Set-Cookie": ["_oauth2_proxy_csrf=; Path=/; Expires=Mon, 24 Jun 2024 02:17:39 GMT; HttpOnly","_oauth2_proxy=8zM_Pcfpp_gesKFe4SMg08o5Iv0A8WAOQOmG1-vZBbQ56UggYVC0Cu-gFMEoxJZU5q1O5vqRlVBizlLetgVjRCksGVbttwl8tQ7h5YiyIubbbtvF1T4JzLh3QfzUUrwbB-VznOkh8qLbjAhddocecjBt4rMiDyceKXqMr4eO5TUEMx4vHtJYnTYalMeTYhGXk5MNSyrdZX9NnQnkdrCjiOQM13ggwob2nYwhGWaAlgzFSWkgkdtBy2Cl_YMWZ8_gKk9rDX289-JrJyGpr5k9O9RzRhZoY2iE3Mcr8-Q37RTji1Ga22QO-XkAcSaGqY1Qo7jLdmgZTYKC5JvtdLc4rj3vcbveYxU7R3Pt2vEribQjKTh4Sqb0aA03p4cxXyZN4SUfBW1NAOm4JLPUhKJy8frqC9_E0nVqPvpvnacaoQs8WkX2zp75xHoMa3SD6KZhQ5JUiPEiNkOaUsyafLvht6lLkNDhgzW3BP2czoe0DCDBLnsot0jH-qQpMZYkaGr-ZnRKI1OPl1vHls3mao5juOAW1VB2A9aughgc8SJ55IFZpMfFMdHdTDdMqPODkItX2PK44GX-pHeLxkOqrzp3GHtMInpL5QIQlTuux3erm3CG-ntlUE7JBtN2T9LEb8XfIFu58X9_vzMun4JQlje2Thi9_taI_z1DSaTtvNNb54wJfSPwYCCl4OsH-BacVmPQhH6TTZ6gP2Qsm5TR2o1U2D9fuVkSM-OPCG9l3tILambIQwC3vofMW6X8SIFSmhJUDvN7NbwxowBiZ6Y7GJRZlAk_GKDkpsdrdIvC67QqczZFphRVnm6qi-gPO41APCbcO6fgTwyOhbP3RrZZKWSIqWJYhNE3_Sfkf0565H7sC7Hc8XUUjJvP3WnjKS9x7KwzWa-dsUjV3-Q-VNl-rXTguVNAIirYK-qrMNMZGCRcJqcLnUF0V_J2lVmFyVsSlE3t0sDw2xmbkOwDptXFOjQL5Rb4esUMYdCBWFajBfvUtcZEFtYhD0kb6VcbjXO3NCVW5qKh_l9C9SRCc7TG1vcRAqUQlRXHacTGWfcWsuQkCJ3Mp_oWaDxs1GRDykQYxAn5sTICovThWEU2C6o75grWaNrkj5NU-0eHh3ryvxLmGLBOXZV9OQhtKShWmUgywSWMxOHOuZAqdAPULc8KheuGFjXYp-RnCbFYWePJmwzfQw89kSkj1KUZgMYwKEjSz62z2qc9KLczomv76ortQzvo4Hv9kaW6xVuQj5R5Oq6_WMBOqsmUMzcXpxCIOGjcdcZRBc0Fm09Uy9oV1PRqvAE4PGtfyrCaoqILBix8UIww63B07YGwzQ-hAXDysBK-Vca2x7GmGdXsNXXcTgu00bdsjtHZPDBBWGfL3g_rMAXr2vWyvK4CwNjcaPAmrlF3geHPwbIePT0hskBboX1v1bsuhzsai7rGM4r53pnb1ZEoTQDa1B-HyokFgo14XiwME0zE1ifpNzefjpkz1YY2krJlqfCydNwoKaTit4tD2yHlnxAeFF9iIrxzSKErNUFpmyLa7ge7V33vhEH-6k5oBTLE2Q2BrC6aAkLCcPwU9xv_SzBDQPRY0MEYv3kGF03Swo1crRbGh-aifYX9NiHDsmG6r1vAnx0MAOw2Jzuz2x6SSdfBrzlcoWBlrwiZzd9kAKq75n1Uy9uzZ8SRnkBrEZySHBwEbu196VklkRE0jqwC-e3wWNNuviSOfwkVeX-7QdOoO10yw9VK2sW52lFvIEf4chv_ta7bGfAZOWBjpktG6ZLD81SE6A88zpqG2SysSyNMp9hl-umG-5sFsjCn_c9E8bDvwkUOUVb9bNqhBDsZgR0BNPawiOZjmyfhzmwmWf-zgFzfFSV6BvOwNRi3sCOHTsWcuk9NBQ_YK8CpNkVl3WeIBSDfidimuC_QV9UWKs1GPk35ZRkM4zKtLY2JsBFWKaDy_P80TcOzcMBoP8gIBClXZ-WUqfE8s1yyc4jrq-qL1_wJ24ef1O9FktsbyZiDKXw2vnqsT8-g_hCeG-unrT1ZFscf8oNdqczARHX-K4vKH2k3uIqEx1M=|1719199056|2rsgdUIClHNEpxBLlHOVRYup6e4oKensQfljtmn4B80=; Path=/; Expires=Mon, 01 Jul 2024 03:17:36 GMT; HttpOnly"
]
- 校驗是否存在此 cookie,并且 cookie 中存儲了用戶的 token 信息同時查看是否過期
11.使用含有 Authorization 頭部存儲用戶的 access_token 訪問相應的 API
curl --url "foo.bar.com/headers"--header "Authorization: Bearer eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIiwiaXNzIjoiaHR0cHM6Ly9kZXYtbzQzeGIxbXo3eWE3YWNoNC51cy5hdXRoMC5jb20vIn0..WP_WRVM-y3fM1sN4.fAQqtKoKZNG9Wj0OhtrMgtsjTJ2J72M2klDRd9SvUKGbiYsZNPmIl_qJUf81D3VIjD59o9xrOOJIzXTgsfFVA2x15g-jBlNh68N7dyhXu9237Tbplweu1jA25IZDSnjitQ3pbf7xJVIfPnWcrzl6uT8G1EP-omFcl6AQprV2FoKFMCGFCgeafuttppKe1a8mpJDj7AFLPs-344tT9mvCWmI4DuoLFh0PiqMMJBByoijRSxcSdXLPxZng84j8JVF7H6mFa-dj-icP-KLy6yvzEaRKz_uwBzQCzgYK434LIpqw_PRuN3ClEsenwRgIsNdVjvKcoAysfoZhmRy9BQaE0I7qTohSBFNX6A.mgGGeeWgugfXcUcsX4T5dQ"
- 后端服務根據 access_token 獲取用戶授權信息并返回對應的 HTTP 響應
{"email": "******","email_verified": false,"iss": "https://dev-o43xb1mz7ya7ach4.us.auth0.com/","aud": "YagFqRD9tfNIaac5BamjhsSatjrAnsnZ","iat": 1719198638,"exp": 1719234638,"sub": "auth0|665d71e74c131177be66e607","sid": "ct2U8_YQ-zT7E8i0E3MyK-z79diVQhaU"
}
用戶令牌刷新
- 訪問用戶受保護的資源(需要認證授權訪問的 API)
curl --url "foo.bar.com/headers"
-
檢查 AccessToken 令牌的過期時間,如果過期或者即將過期,請求刷新令牌
-
如果在 cookie 中檢測到存在 refresh_token,則可以訪問相應的接口以交換新的 id_token,access_token
curl -X POST \--url "https://dev-o43xb1mz7ya7ach4.us.auth0.com/oauth/token" \--data "grant_type=refresh_token" \--data "client_id=YagFqRD9tfNIaac5BamjhsSatjrAnsnZ" \--data "client_secret=ekqv5XoZuMFtYms1NszEqRx03qct6BPvGeJUeptNG4y09PrY16BKT9IWezTrrhJJ" \--data "refresh_token=GrZ1f2JvzjAZQzSXmyr1ScWbv8aMFBvzAXHBUSiILcDEG"
-
更新會話,并存儲新的令牌
-
攜帶 Authorization 標頭并使用新的 access_token 訪問對應 API
-
后端服務根據 access_token 獲取用戶授權信息并返回對應的 HTTP 響應
云原生網關中的認證鑒權能力
云原生 API 網關支持以下三類認證鑒權的方式,用戶可以按照自己的業務場景選擇適合的認證類型和方式。
云原生 API 網關的其他安全能力
保護 API 安全,是云原生 API 網關作為接入層重要的能力,認證鑒權只是云原生 API 網關諸多安全能力中的一部分;云原生網關還提供下表中的多種安全能力,以便用戶進一步維護企業API資產的安全。
相關鏈接:
【1】What is openAPI:
https://swagger.io/docs/specification/v3_0/about/