保護 Web 服務的 OAuth 2.0 代理重新整理令牌

Azure CLI
Azure DevOps
Azure Functions
Azure 金鑰保存庫
Azure Pipelines

開發 Web 服務時,您可能需要使用 OAuth 2.0 代理者 (OBO) 流程取得令牌。 OBO 流程提供應用程式叫用服務或 Web API 的使用案例,而 Web API 接著需要呼叫另一個服務或 Web API。 OBO 會透過要求鏈結傳播委派的使用者身分識別和許可權。 當應用程式需要無限期地使用存取和重新整理令牌時,通常是在離線存取案例中,請務必安全地儲存重新整理令牌。

警告

請仔細考慮儲存任何安全性令牌的風險和責任,因為這些令牌可讓惡意執行者存取組織 Microsoft Entra 標識符所保護的資源。 以任何組織目錄中帳戶為目標的應用程式 安全性缺口(任何 Microsoft Entra 目錄 - 多租使用者) 可能會特別災難性。

儲存存取令牌會造成更大的安全性風險,因為中的存取令牌本身可以存取資源。 建議的方法不是儲存存取令牌,而是視需要取得存取令牌。 安全地儲存重新整理令牌,其嚴謹程度與存取令牌一樣嚴格。

如有必要,如果重新整理令牌遭到入侵,您可以 撤銷這些令牌

潛在的使用案例

此解決方案使用 Azure 金鑰保存庫、Azure Functions 和 Azure DevOps 安全地更新及儲存 OBO 重新整理令牌。

架構

顯示金鑰和令牌重新整理程式的圖表。

下載此架構的 Visio 檔案

資料流程

  • Azure 金鑰保存庫 保留每個 Microsoft Entra ID 租使用者的秘密加密密鑰。
  • Azure Functions 定時器觸發的函式會從 金鑰保存庫 取得最新的秘密密鑰。 另一個 Azure Functions 函式會從 Microsoft 身分識別平台 擷取重新整理令牌,並使用最新的秘密密鑰版本加以儲存。
  • 資料庫會儲存最新的加密金鑰和不透明數據。
  • Azure DevOps 持續傳遞管線會管理和同步秘密輪替和令牌重新整理程式。

如果您已經在使用管線進行基礎結構即程式代碼 (IaC) 或持續整合和傳遞 (CI/CD),Azure Pipelines 是新增密鑰輪替策略的便利位置。 只要限制設定和擷取秘密的路徑,就不需要使用 Azure Pipelines。

套用下列原則,以允許 Azure DevOps 服務連線的服務主體在 金鑰保存庫 中設定秘密。 將 <Key Vault Name><Service Connection Principal> 變數取代為您環境的正確值。

az keyvault set-policy --name $<Key Vault Name> --spn $<Service Connection Principal> --secret-permissions set

設定 Azure Pipelines 以建立和更新金鑰之後,您可以排程管線定期執行。 管線會更新 金鑰保存庫 秘密以與金鑰輪替同步,並使用新的秘密版本儲存加密的令牌。 如需詳細資訊,請參閱 設定管線的排程。

受控識別

Azure Functions 等 Azure 服務存取 金鑰保存庫 的慣用方式是使用服務的受控識別。 您可以透過 Azure 入口網站、Azure CLI 或 IaC 案例的 Azure Resource Manager (ARM) 樣本來授與存取權。

Azure 入口網站

在 Azure 入口網站 中,新增 金鑰保存庫 存取原則,以允許 Azure Functions 受控識別物件標識元取得設定秘密。 如需詳細資訊,請參閱新增系統指派的身分識別和使用App Service和 Azure Functions 的 金鑰保存庫 參考。

顯示如何在 Azure 入口網站 中啟用受控識別的螢幕快照。

Azure CLI

您也可以使用 Azure CLI 來設定 Azure 金鑰保存庫 原則:

az keyvault set-policy --name $<Key Vault Name> --spn $<Service Connection Principal> --secret-permissions set
az keyvault set-policy --name $<Key Vault Name> --spn $<Managed Identity Principal> --secret-permissions get

ARM 範本

下列 ARM 範本可讓 Azure Functions 存取 Azure 金鑰保存庫。 以 *** 您環境的正確值取代變數。

{
  "type": "Microsoft.KeyVault/vaults",
  "apiVersion": "2019-09-01",
  "name": "***",
  "location": "***",
  "properties": {
    "sku": {
      "family": "A",
      "name": "standard"
    },
    "tenantId": "***",
    "enableSoftDelete": true,
    "enabledForDeployment": false,
    "enabledForTemplateDeployment": false,
    "enabledForDiskEncryption": false,
    "accessPolicies": [
      {
        "tenantId": "***",
        "objectId": "<Managed Identity Principal>",
        "permissions": {
          "secrets": [
            "get"
          ]
        }
      },
      {
        "tenantId": "***",
        "objectId": "<Service Connection Principal>",
        "permissions": {
          "secrets": [
            "set"
          ]
        }
      }
    ]
  }
}

令牌記憶體

您可以使用任何資料庫,以加密形式儲存令牌。 下圖顯示將重新整理權杖儲存在資料庫中的順序:

顯示新增令牌順序的圖表。

序列有兩個函式和 userId()secretId()。 您可以將這些函式定義為、 token.tidtoken.subtoken.oid一些組合。 如需詳細資訊,請參閱 使用id_token

將密碼編譯金鑰儲存為秘密,您可以在 Azure 金鑰保存庫 中查閱最新版本的金鑰。

令牌使用方式

使用金鑰很簡單。 下列順序會根據最新的金鑰版本來查詢金鑰。

顯示預存令牌使用順序的圖表。

令牌重新整理與函式是正交DoWork的,因此 Azure Functions 可以使用 Durable Functions 以異步方式執行DoWork和令牌重新整理。 如需使用 Durable Functions 的 HTTP 觸發函式詳細資訊,請參閱 HTTP 功能

不建議在 HTTP 要求管線中使用 Azure 金鑰保存庫,因此請隨時快取回應。 在此範例中,金鑰保存庫 對呼叫的回應是可快取的getSecret(secretId, secretVersion)

金鑰輪替和令牌重新整理

您可以在重新整理令牌的同時輪替秘密密鑰,讓最新的令牌使用最新版本的加密密碼加密。 此程式會針對定時器觸發程式使用內建的 Azure Functions 支援。 如需詳細資訊,請參閱 Azure Functions 的定時器觸發程式。

下列順序圖說明使用金鑰輪替同步處理權重新整理的程式:

顯示使用金鑰輪替同步處理令牌重新整理順序的圖表。

用戶和訪問控制

Microsoft 身分識別平台 可讓您在遭到入侵時撤銷重新整理令牌。 請參閱 令牌撤銷Revoke-AzureADUserAllRefreshToken

注意

Azure AD Powershell 計劃於 2024 年 3 月 30 日淘汰。 若要深入瞭解,請閱讀 淘汰更新

建議您移轉至 Microsoft Graph PowerShell ,以與 Microsoft Entra ID (先前稱為 Azure AD) 互動。 Microsoft Graph PowerShell 允許存取所有 Microsoft Graph API,並可在 PowerShell 7 上使用。 如需常見移轉查詢的解答,請參閱 移轉常見問題

若要從 Microsoft Entra ID 移除使用者,只要移除用戶的記錄即可。 若要移除每個使用者的應用程式存取權,請移除 refreshToken 用戶數據的一部分。

若要移除使用者群組的存取權,例如目標租使用者中的所有使用者,您可以使用 Azure Pipelines 根據 來刪除群組的秘密 secretId()

參與者

本文由 Microsoft 維護。 原始投稿人如下。

主體作者:

下一步