Authorization: SSWS <api_token_value>
Accept: application/json
Host: dev-1234567.okta.com

API的調用者(又稱客戶端)將令牌值添加到調用中。根據調用的供應商系統,API可能會將靜態令牌值添加到 HTTP 標頭,如授權(使用標準授權方案或專有授權方案,如 Okta 的 SSWS 方案),或添加到查詢參數中。

從靜態 API 標記轉向 OAuth 2.0,以提高安全性

與許多技術一樣,這種易用性也會相應增加風險。與壽命較短的 OAuth 2.0 令牌不同,靜態令牌的壽命通常較長。設置在查詢參數中的 API 標記尤其危險。瀏覽器會將 URL 保存在歷史記錄中,日志系統可能會記錄整個 URL,從而比使用 HTTP 標頭更容易暴露令牌。

為了更好地理解與靜態 API 令牌相關的安全問題,讓我們來詳細研究它們的一些特性,并與作為替代方案的 OAuth 2.0 進行對比。

使用靜態API令牌時的訪問風險

靜態令牌可能落入壞人之手,導致未經授權的訪問。例如,靜態令牌可能無意中被檢查到源代碼控制系統中,從而無意中將令牌暴露給版本庫查看器和源代碼控制歷史。由于靜態令牌的壽命較長,因此令牌暴露的風險尤其令人擔憂,因為被盜令牌的后果會造成嚴重影響——被盜的靜態令牌在手動停用或最終過期之前一直處于激活狀態,從而允許未經授權的訪問。

代幣輪換問題

旋轉靜態令牌是一項具有挑戰性的任務。由于令牌值會在調用者的環境或軟件系統中持續存在,因此要在保持生產環境正常運行的情況下快速釋放令牌、生成新的令牌并保存令牌,這對輪換的時間安排提出了挑戰。

難以限制范圍

為靜態令牌分配有限的作用域并不簡單。靜態令牌通常授予對所調用 API 的全部訪問權限–一種全有或全無的訪問級別。為有限范圍定義訪問權限(如只讀訪問權限與寫入訪問權限)以及其他細粒度訪問控制措施,可能無法通過靜態 API 標記來實現或難以管理。

用戶生成的令牌中的繼承權限

用戶生成的訪問令牌通常采用生成令牌的用戶賬戶權限。如果一個管理員生成了令牌,那么它就可以完全訪問管理員可以執行的所有資源和操作。為了減輕這種擔憂,有時企業會設置范圍有限的服務賬戶來生成令牌。然而,這樣做會導致用戶管理費用增加,并有可能占用許可證。

審計挑戰

跟蹤靜態令牌的使用情況非常棘手。審計的核心需求是跟蹤用戶與 API 的交互。但是,靜態 API 標記通常沒有用戶上下文,而且對 API 的所有調用都使用相同的靜態標記,因此可能無法識別特定用戶對 API 的操作。

靜態令牌很脆弱

當用戶退出組織時,與用戶賬戶關聯的令牌就會失效。有些組織使用服務賬戶來抵消這一措施,但這會帶來訪問風險和管理開銷。

有一種更好、更安全的方法可以訪問 API,從而降低與靜態 API 標記相關的風險:使用行業標準 OAuth 2.0 流程。

擁抱 OAuth 2.0 以提高安全性

OAuth 2.0 幾乎可以滿足任何場景的需求,以取代靜態令牌(如 Okta 的 SSWS 令牌)。但與靜態令牌不同的是,OAuth 規范包括令牌輪換、基本授權決定等日常使用案例所必需的定義和安全實踐,例如:

OAuth 2.0 通過向集中式授權服務器發送請求中的配置屬性,支持上述每種日常使用情況。一般的交互是這樣一個多步驟過程:

  1. 調用者向授權服務器請求一個訪問令牌,并傳遞用例所需的配置屬性。授權服務器返回一個短期訪問令牌。令牌的壽命取決于用例。有些用例本質上更安全,因此使用期限會有所不同。下面的 HTTP 請求顯示了一個檢索令牌的請求示例,但不包括所需的配置屬性。你將在接下來的示例中看到必要的配置屬性。
POST  /token HTTP/1.1
Host: authorization-server.com

<plus required configuration properties + credentials>
GET /api/products HTTP/1.1
Authorization: Bearer <api_token_value>
Accept: application/json
Host: dev-1234567.okta.com

OAuth 2.0 的內容非常豐富,因此請查看本文章末尾的資源以了解更深入的內容。我們不會在這篇文章中深入探討所有細節,但會針對所提到的用例提供具體信息,并為每個用例提供高級摘要。

讓我們看看每個用例,了解 OAuth 2.0 如何支持這些用例。

服務與服務之間的互動

您可能有調用其他應用程序接口獲取數據或執行操作的后端流程。OAuth 2.0 支持服務對服務或機器對機器的請求,而不需要使用稱為 “客戶端憑證 “的授權流來關聯調用的用戶上下文。

使用客戶端憑據相對于 API 令牌的優勢

與靜態 API 密鑰相比,使用 OAuth 2.0 進行服務間交互具有巨大優勢,尤其是在稱為作用域的訪問級別方面。在 OAuth 2.0 中,您可以將訪問令牌獲取的作用域作為調用配置屬性的一部分來識別,以檢索您的令牌。您需要確保您調用的 API 支持基于作用域的訪問,并且您已經授予了所需作用域的訪問權限。例如,Okta API為資源API定義了多個作用域,如okta.users.read和okta.users.write。您可以授予其中一個或兩個作用域的訪問權限。

客戶端憑證流程與使用服務賬戶進行 API 授權不同。OAuth 2.0 支持以標準格式進行機器到機器的交互,而無需占用用戶席位來模擬自動化用戶。請注意,當你定義作用域時,是在服務應用程序的配置和授權服務器中定義的,而不是在用戶級別定義的。這樣做的好處是,你可以控制整個服務應用程序的資源訪問,而不是通過應用程序中的某個用戶。您不必再擔心服務賬戶的管理問題,而且可以確信應用程序訪問的范圍不會超過您所允許的范圍。

使用客戶端憑據檢索訪問令牌

要檢索此流程的訪問令牌,需要發送指定授權流程類型、憑據和訪問令牌作用域的屬性。定義授權流的 OAuth 2.0 術語稱為 grant_type;對于客戶憑據流,你要傳遞的值是 client_credentials。

憑證可以是用客戶端私鑰簽名的加密安全 JSON Web 令牌(JWT),也可以是從授權服務器生成的秘密值。私鑰 JWT 更為安全,因為你不會冒著暴露秘密值的風險,從而意外地創建與靜態 API 令牌類似的訪問問題。您將生成一對公鑰/私鑰,并在 JSON 網絡密鑰集 (JWKS) 中注冊公鑰或將其上傳到授權服務器,這樣授權服務器就有了驗證 JWT 簽名的公鑰。有關此過程的更多信息,請參閱通過服務應用程序為 Okta 實施 OAuth 文檔。

用于檢索訪問令牌的 HTTP 調用示例可能如下所示:

POST  /token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Accept: application/json
Host: authorization-server.com

grant_type=client_credentials
&scope=okta.users.read
&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
&client_assertion=<generated_jwt>

獲得訪問令牌后,您可以將其作為標頭添加到 API 調用中:Authorization: Bearer access_token

了解更多有關使用 .NET 進行服務對服務 API 調用和在 Python 中創建私有 JWT 的信息,請參閱《保護您的 .NET 6 Web API》和《在三個 Python 命令中設置私鑰 JWT 流程》。

基于任務的自動化

命令行終端(如 Bash 和 PowerShell)是在終端窗口內運行單個命令或腳本的無瀏覽器進程。與之前的服務間交互不同,該流程涉及用戶上下文。您希望在授權上下文下運行命令行操作,這意味著您只能訪問您應該擁有的 API 資源。OAuth 2.0 通過一個名為設備流(Device Flow)的流程支持這種用例。

在此流程中,獲取訪問令牌是一個多步驟過程。在像服務對服務用例那樣直接請求訪問令牌之前,首先要將客戶 ID 發送到授權服務器上的一個特殊端點,從而獲得唯一的驗證碼:

POST  /device/authorize HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Host: authorization-server.com

client_id=<client_ID>

/device/authorize 調用的響應會返回兩個唯一代碼(設備代碼和用戶代碼)和一個驗證 URI。通過瀏覽器導航到驗證 URI 并輸入用戶代碼,確認授權請求。

要檢索訪問令牌,需要在調用中添加 grant_type 屬性,以指定用例的 OAuth 2.0 流程和設備代碼作為配置屬性:

POST  /token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Host: authorization-server.com

client_id=<client_ID>
&grant_type=urn:ietf:params:oauth:grant-type:device_code
&device_code=device_code

在 Authorization.Bearer access_token 頭信息中使用響應中的訪問令牌:Bearer access_token 頭信息。

有關命令行設備代碼流程的更多信息,請參閱《使用 Java 從命令行進行身份驗證》(Authenticate from the Command Line with Java)。

用戶通過 Web 應用程序訪問

最后一個用例確保用戶的授權適用于使用網絡應用程序時的 API 訪問。OAuth 2.0 支持將應用程序的操作限制在用戶可以進行的操作和看到的數據的子集范圍內。在此流程中,您可以使用用戶上下文來申請資源授權,此外,有了用戶上下文,對單個用戶調用的審計和跟蹤也會變得更加簡單。此用例的 OAuth 2.0 流程結合了標準流程、授權代碼流程和一個額外安全層的擴展,稱為代碼交換證明密鑰(PKCE)。

帶有 PKCE 的授權代碼流需要多個步驟才能檢索訪問令牌,并涉及通過同意和驗證進行的用戶交互,從而實現多因素身份驗證。在此流程中,您將把用戶重定向到授權服務器,在請求訪問令牌之前獲取授權碼。

重定向 URL 包含特定于請求的屬性,以便用戶完成登錄,包括使用 response type 屬性指定請求類型和客戶端 ID 等屬性。

https://<identity_provider_uri>/authorize?response_type=code&client_id=<client_ID>&+remaining props

當用戶成功完成登錄后,身份提供程序會重定向到應用程序,并在授權響應中提供授權代碼。要檢索訪問令牌,需要輸入該流程的授權類型、授權代碼和其他特定于請求的元數據。

POST  /token HTTP/1.1
Host: authorization-server.com

grant_type=code
&code=<code_response>
&client_id=<client_ID>

有了訪問令牌后,網絡應用程序就可以在 “授權”(Authorization:Bearer access_token 標頭。

有關授權代碼流的更多信息,請參閱《SPA 的身份驗證和授權工作原理》和《將 PKCE 與 OAuth 2.0 和 Spring Boot 結合使用以提高安全性》。

逐步淘汰靜態 API 令牌并使用 OAuth 2.0

軟件遷移需要時間和規劃,制定一個好的游戲計劃會有所幫助。考慮以小步漸進的方式過渡到 OAuth 2.0。

從靜態 API 標記遷移的第一步是確保您使用的 API 支持 OAuth 2.0。如果要調用第三方 API,請向供應商咨詢。如果您的 API 是內部 API,則需要添加 OAuth 支持。一旦驗證您調用的 API 支持 OAuth,您就需要 OAuth 應用程序的客戶端 ID,并啟用訪問措施(如作用域)。

以管理員身份登錄到 Okta 管理控制臺后,您就可以確定是否在 Okta 環境中使用靜態 API 標記。在側邊欄中,導航到 “安全性”>”API”,然后選擇 “令牌 “選項卡,就可以看到為 Okta 組織創建的所有令牌。通過該視圖可以了解 API 令牌的使用情況、用例和訪問級別(例如,超級管理員創建的令牌具有完全訪問權)。您需要對每個令牌進行評估,并將其轉換為使用 OAuth。

讓我們重點關注自動服務對服務調用的用例。將 OAuth 2.0 集成到您的應用程序接口中是一件非常困難的事情,因此讓我們來看看如何逐步實現這一目標。在進行任何代碼修改之前,您可以在本地手動嘗試這些步驟,并使用您最喜歡的 HTTP 客戶端請求一個令牌,然后使用 OAuth 2.0 調用 API。本例使用帶有私鑰 JWT 的客戶端憑證流。步驟如下

  1. 生成公鑰/私鑰對
  2. 使用公鑰/私鑰對生成私鑰 JWT
  3. 請求訪問令牌
  4. 將訪問令牌添加到 API 請求中
  5. 將 OAuth 納入應用系統

生成公鑰/私鑰對

您可以按照以下說明生成一對公鑰/私鑰。如果您不想自己生成公鑰對,Okta 的管理控制臺可以生成一個公鑰對/私鑰對用于測試。

生成私鑰JWT

按照 “使用服務應用程序為 Okta 實施 OAuth “文檔中的說明,使用公鑰/私鑰對創建私鑰 JWT。在這一步,更重要的是了解這一切是如何工作的,而不是自動執行步驟,因此您可以將公/私鑰對存儲在本地,使用安裝在您機器上的工具,并將包含您公鑰的 JWKS 粘貼到測試 JWT 生成器網站上。

請求訪問令牌

使用你的私鑰 JWT 請求訪問令牌,在你喜歡的 HTTP 客戶端中發出 HTTP 請求,不要添加任何作用域。在沒有適當作用域的情況下使用訪問令牌時應該會出錯,但測試出錯和路徑正確是好事。訪問令牌會在某個時間過期,你會在訪問令牌響應中看到過期時間。訪問令牌是響應的一部分。您將使用整個字符串作為訪問令牌。

將訪問令牌添加到您的 API 請求中

使用 HTTP 客戶端,使用訪問令牌調用 API。您將添加一個授權標頭并使用承載器方案,這樣您的 API 調用就會有如下格式的標頭:

Authorization: Bearer <access_token>

調用 API 時,您應該會收到 HTTP 狀態為 403 的錯誤信息。耶!成功了嗎?是的,一次成功的錯誤案例測試。現在您知道如果配置范圍時出現錯誤會出現什么錯誤了。讓我們把作用域添加到訪問令牌請求中,然后再試一次。

這次,使用私鑰 JWT 申請訪問令牌,并為 API 調用添加作用域。在 API 調用中使用訪問令牌。真相時刻!你應該看到一個成功的響應。如果再次出現 403 錯誤,就說明存在配置錯誤。如果出現這種情況,請仔細檢查請求作用域,并確保 OAuth 2.0 應用程序已啟用您請求的作用域。

在系統中添加OAuth 2.0授權

現在,您已經成功地手動完成了服務器到服務調用的 OAuth 2.0 授權,可以將這些步驟的各個方面引入您的系統。在開發或測試環境中,嘗試使用訪問令牌。您需要更改 API 以使用帶承載器方案格式的授權標頭,并用手動生成的訪問令牌替換現有的靜態 API 令牌,以確保您的 API 調用在不自動請求訪問令牌的情況下也能正常工作。

當您確信 API 系統能成功處理訪問令牌時,就可以在代碼中添加請求訪問令牌的步驟了。您的技術棧可能有 SDK,至少可以協助完成部分(或全部)請求步驟。Okta 的管理 SDK 可以代表您處理 OAuth 2.0 握手。Java Spring 用戶可以查看 Spring Security 文檔,.NET Core 用戶可以查看 Microsoft.AspNetCore.Authentication 作為示例。請記住,在進行過程中要測試您的工作是否順利、是否存在錯誤案例以及是否正確處理了訪問令牌過期等情況。

在將更改部署到生產環境之前,請確保使用生產質量工具在內部生成 JWKS 并安全地管理私鑰。

API授權遷移期間的最佳實踐

立即從靜態令牌過渡并不總是可行,特別是在大型組織中或者如果您有大量 API 需要更新。如果您仍在 Okta 中使用 SSWS 令牌,那么您希望在過渡到 OAuth 2.0 之前降低風險。最佳實踐包括:

  1. 使用 OAuth 2.0 實施新的 API 調用或代碼。
  2. 遵循最小特權原則。例如:

不要使用個人帳戶建立服務帳戶。

對服務帳戶使用自定義管理員角色,僅授予基本權限。

使用組和全局會話策略來防止服務帳戶的交互式登錄。

使用 OAuth 2.0 保護 API 調用

從靜態令牌轉向 OAuth 2.0 不僅僅是為了擁抱新技術,更是為了轉向一個更安全、更靈活、對開發人員更友好的生態系統。雖然靜態令牌有其存在的時間和位置,但很明顯,未來將是動態的、以用戶為中心的、安全的 OAuth 2.0 解決方案。

請記住,隨著技術的進步,保持更新并適應更好的實踐不僅有益,而且至關重要。遷移到 OAuth 2.0,踏上更安全、更簡化、更高效的開發之旅。

OAuth 2.0 的后續步驟

如果您覺得這篇文章有趣,您可能會喜歡這些帖子。

查看 Okta 的API 安全開發人員指南,開始遷移到 OAuth 2.0:

配置展示所有權證明

為 Okta 配置 OAuth

保護您的 API 端點

整合第三方風險

使用 ACR 值設置逐步身份驗證

原文鏈接:Why You Should Migrate to OAuth 2.0 From Static API Tokens

上一篇:

當您達到每月 API 速率限制時會發生什么?

下一篇:

在線API描述規范、發現與文檔入門
#你可能也喜歡這些API文章!

我們有何不同?

API服務商零注冊

多API并行試用

數據驅動選型,提升決策效率

查看全部API→
??

熱門場景實測,選對API

#AI文本生成大模型API

對比大模型API的內容創意新穎性、情感共鳴力、商業轉化潛力

25個渠道
一鍵對比試用API 限時免費

#AI深度推理大模型API

對比大模型API的邏輯推理準確性、分析深度、可視化建議合理性

10個渠道
一鍵對比試用API 限時免費