開發 Web 服務時,您可能需要使用 OAuth 2.0 代理者 (OBO) 流程取得令牌。 OBO 流程提供應用程式叫用服務或 Web API 的使用案例,而 Web API 接著需要呼叫另一個服務或 Web API。 OBO 會透過要求鏈結傳播委派的使用者身分識別和許可權。 當應用程式需要無限期地使用存取和重新整理令牌時,通常是在離線存取案例中,請務必安全地儲存重新整理令牌。
警告
請仔細考慮儲存任何安全性令牌的風險和責任,因為這些令牌可讓惡意執行者存取組織 Microsoft Entra 標識符所保護的資源。 以任何組織目錄中帳戶為目標的應用程式 安全性缺口(任何 Microsoft Entra 目錄 - 多租使用者) 可能會特別災難性。
儲存存取令牌會造成更大的安全性風險,因為中的存取令牌本身可以存取資源。 建議的方法不是儲存存取令牌,而是視需要取得存取令牌。 安全地儲存重新整理令牌,其嚴謹程度與存取令牌一樣嚴格。
如有必要,如果重新整理令牌遭到入侵,您可以 撤銷這些令牌 。
潛在的使用案例
此解決方案使用 Azure 金鑰保存庫、Azure Functions 和 Azure DevOps 安全地更新及儲存 OBO 重新整理令牌。
架構
資料流程
- 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 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.tid
和 token.sub
的token.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 維護。 原始投稿人如下。
主體作者:
- Jason Mostella |資深軟體工程師