使用 Microsoft.Identity.Web 的客戶端秘密

用戶端秘密是在應用程式向 Microsoft 身份識別平台請求令牌時用來證明其身份的字串值。 Microsoft。Identity.Web 支援用戶端秘密作為機密用戶端應用程式的多種憑證類型之一。

這很重要

用戶端秘密應僅用於 開發與測試環境中。 對於生產工作負載,請使用 憑證無憑證認證資訊,如受管理的身份或聯邦身份憑證。 客戶端秘密比憑證憑證更容易被入侵,且無法針對特定操作進行範圍限制。

選擇認證類型

機密用戶端應用程式需要憑證才能與 Microsoft 身分識別平台 進行認證。 Microsoft。Identity.Web 透過 ClientCredentials 設定區塊支援以下憑證類型:

認證類型 推薦環境 安全等級
客戶端密碼 開發與測試
證書 舞台設計與製作
受控識別 在 Azure 上托管的生產環境 最高
聯合身分識別 CI/CD,Kubernetes

用戶端秘密是簡單字串,會在 Microsoft Entra ID 中註冊到你的應用程式。 雖然它們是最容易設定的憑證類型,但同時也有重大的安全限制:

  • 它們可能被意外暴露在原始碼、日誌或設定檔中。
  • 它們有有效期限,必須手動旋轉。
  • 除了擁有機密外,他們不會提供來電者身份的密碼學證明。

在 appsettings.json 設定客戶端秘密

若要設定客戶端秘密,請在您的ClientCredentials檔案的AzureAd區塊中新增一個appsettings.json陣列:

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "YOUR_TENANT_ID",
    "ClientId": "YOUR_CLIENT_ID",
    "ClientCredentials": [
      {
        "SourceType": "ClientSecret",
        "ClientSecret": "YOUR_SECRET_VALUE"
      }
    ]
  }
}

陣列 ClientCredentials 支援多個項目。 Microsoft。Identity.Web 會依序嘗試每個憑證直到成功,這對於秘密輪替情境非常有用。

警告

絕對不要把實際的祕密值提交給原始碼控制。 YOUR_SECRET_VALUE前述範例中的佔位符必須以安全儲存的參考替代,詳見後續章節。

儲存開發用秘密

本節說明如何在本地開發時將秘密值排除在原始碼之外。

.NET 使用者秘密

在本地開發期間,建議用秘密 管理器工具來儲存秘密。 使用者機密將敏感資料儲存在專案樹之外,防止意外提交到版本控制。

  1. 為您的專案初始化使用者秘密:

    dotnet user-secrets init
    
  2. 設定客戶端的秘密值:

    dotnet user-secrets set "AzureAd:ClientCredentials:0:ClientSecret" "your-secret-value"
    
  3. 確認秘密是否被儲存:

    dotnet user-secrets list
    

使用者秘密會在使用DevelopmentWebApplication.CreateBuilder()時自動載入Host.CreateDefaultBuilder()環境中。

你的 appsettings.json S 應該包含結構體,但不包括實際的秘密值。

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "YOUR_TENANT_ID",
    "ClientId": "YOUR_CLIENT_ID",
    "ClientCredentials": [
      {
        "SourceType": "ClientSecret"
      }
    ]
  }
}

環境變數

你也可以用環境變數來提供客戶端秘密。 .NET配置會自動將使用 __(雙重底線)分隔符的環境變數映射到組態階層。 為你的殼設定變數:

$env:AzureAd__ClientCredentials__0__ClientSecret = "your-secret-value"

環境變數優先於 中的 appsettings.json值,因此你的組態檔案中的秘密值可以是空的或省略的。

儲存機密資料以供更高級環境使用

在暫存、品質保證或任何共享環境時,使用 Azure Key Vault 作為設定來源。 此方法能將機密性排除在設定檔與環境變數之外,同時提供稽核、存取政策及自動輪換功能。

將 Azure Key Vault 新增為設定來源

  1. 安裝所需的 NuGet 套件:

    dotnet add package Azure.Extensions.AspNetCore.Configuration.Secrets
    
  2. 將用戶端密鑰存於 Azure Key Vault,並以名稱映射到配置路徑。 使用 -- (雙劃)作為分隔符:

    az keyvault secret set \
      --vault-name "your-keyvault-name" \
      --name "AzureAd--ClientCredentials--0--ClientSecret" \
      --value "your-secret-value"
    
  3. Program.cs 中新增 金鑰保存庫 作為設定來源。 以下程式碼註冊 金鑰保存庫,使其秘密可透過標準設定 API 取得:

    var builder = WebApplication.CreateBuilder(args);
    
    builder.Configuration.AddAzureKeyVault(
        new Uri("https://your-keyvault-name.vault.azure.net/"),
        new DefaultAzureCredential());
    

金鑰保存庫 秘密名稱 AzureAd--ClientCredentials--0--ClientSecret 會自動映射到 AzureAd:ClientCredentials:0:ClientSecret 配置路徑。

小提示

即使使用 金鑰保存庫 來儲存客戶端秘密,也要考慮你的生產工作負載是憑證還是受管理身份更適合。 金鑰保存庫 適合共用開發或暫存環境,但生產環境應使用更強的憑證類型。

在 Azure portal 建立客戶端秘密

請依照以下步驟在 Microsoft Entra ID 註冊您的應用程式的用戶端秘密:

  1. 請登入Microsoft Entra 系統管理中心
  2. 請前往 Identity>Applications>應用程式註冊
  3. 從清單中選取您的應用程式。
  4. 在左側選單中,選擇 「憑證與秘密」。
  5. 選擇 「客戶端秘密 」標籤。
  6. 選擇新用戶端密碼
  7. 新增客戶端秘密 窗格中:
    • 輸入秘密的 描述 (例如「開發秘密」)。
    • 選擇 有效 期限。 可選的選項包括180天、365天、730天或自訂日期。
    • 選取 ,然後新增
  8. 立刻複製秘密值。 這個數值只會顯示一次,且在你離開頁面後無法再取回。

這很重要

建立後立即將秘密值記錄在安全位置。 Microsoft Entra ID 只會在建立時顯示該值。 如果失去該值,你必須建立新的秘密。

管理機密到期與輪換

用戶端機密有最大有效期限,並於建立時指定的日期到期。 規劃秘密輪調以避免應用程式中斷。

監控到期

  • 請查看你申請註冊時「憑證與秘密」頁面的「過期」欄位。
  • 設定 Microsoft Entra recommendations,以便在憑證過期前收到通知。

旋轉策略

使用 ClientCredentials 陣列支援無停機更新。

  1. 在 Azure 入口網站建立一個新的客戶端秘密。

  2. 將新的密碼添加為陣列中的額外項目 ClientCredentials 。 首先放置新的密鑰,以便在嘗試舊的密鑰之前使用它:

    {
      "AzureAd": {
        "ClientCredentials": [
          {
            "SourceType": "ClientSecret",
            "ClientSecret": "[NEW_SECRET_REFERENCE]"
          },
          {
            "SourceType": "ClientSecret",
            "ClientSecret": "[OLD_SECRET_REFERENCE]"
          }
        ]
      }
    }
    
  3. 部署更新後的設定。 Microsoft。Identity.Web 嘗試第一個憑證,若第一個失敗則回退到第二個憑證。

  4. 確認新秘密有效後,將舊秘密從設定和 Azure 入口中移除。

遷移到生產環境憑證

在部署到生產環境前,先從用戶端秘密遷移到更安全的憑證類型:

憑證型驗證

憑證提供密碼學身份證明,是生產環境中推薦使用的憑證類型。 以下設定可從 金鑰保存庫 取得憑證:

{
  "AzureAd": {
    "ClientCredentials": [
      {
        "SourceType": "KeyVault",
        "KeyVaultUrl": "https://your-keyvault-name.vault.azure.net",
        "KeyVaultCertificateName": "your-certificate-name"
      }
    ]
  }
}

詳細步驟請參見 使用憑證與 Microsoft.Identity.Web

管理身份(無憑證)

對於以 Azure 託管的應用程式,受管理身份完全消除了管理憑證的需求。 以下配置使用使用者指派的管理身份:

{
  "AzureAd": {
    "ClientCredentials": [
      {
        "SourceType": "SignedAssertionFromManagedIdentity",
        "ManagedIdentityClientId": "YOUR_MANAGED_IDENTITY_CLIENT_ID"
      }
    ]
  }
}

詳細步驟請參見無憑證身份驗證,使用 Microsoft.Identity.Web

移轉檢查清單

  • [ ] 產生或配置新的憑證(憑證或管理身份)。
  • [ ] 更新你的應用程式設定,使用新的憑證類型。
  • [ ] 在預備環境中測試新憑證。
  • [ ] 部署到生產環境。
  • [ ] 從 Azure 入口網站移除舊的客戶端秘密。
  • [ ] 驗證應用程式在沒有舊秘密的情況下正確運作。

避免常見的安全錯誤

在處理客戶秘密時,請參考以下反模式及其建議的替代方案:

反模式 風險 建議
原始碼中的硬編碼祕密 版本控制中揭露的秘密 使用 User Secrets、環境變數或 金鑰保存庫
秘密承諾appsettings.Development.json 任何有儲存庫存取權限的人都可以看到秘密。 把檔案加入 .gitignore,然後改用 User Secrets。
跨環境分享秘密 開發機密被入侵暴露生產環境 每個環境使用獨特的密鑰
在生產環境中使用祕密 憑證被竊的風險較高 遷移到憑證或受管理的身分識別
創造沒有到期計畫的秘密 密鑰到期時應用程式中斷 設定到期提醒並實作輪替
記錄秘密值 日誌檔案中揭露的秘密 切勿記錄憑證值;只記錄憑證來源類型
在伺服器上以純文字檔案儲存秘密 任何有伺服器存取權的人都能接觸到秘密 使用環境變數或 金鑰保存庫

解決常見錯誤

本節介紹您在設定用戶端秘密時可能遇到的常見錯誤。

不正確的用戶端密碼

錯誤AADSTS7000215: Invalid client secret provided.

可能的原因:

  • 秘密值被錯誤複製。 秘密值可能包含在複製/貼上操作中被截斷的特殊字元。
  • 這個密鑰是為與 ClientId 設定的應用程式註冊不同的其他應用程式所建立的。
  • 設定路徑錯誤,且應用程式無法讀取秘密值。

解決方法:

  1. 在 Azure 入口網站建立新的客戶端秘密,並仔細複製完整值。

  2. 驗證你的ClientIdTenantId設定與秘密建立時的應用程式註冊相符。

  3. 新增斷點或記錄語句以驗證設定已正確地載入:

    // For debugging only — remove before committing
    var config = builder.Configuration.GetSection("AzureAd:ClientCredentials:0:ClientSecret").Value;
    Console.WriteLine($"Secret loaded: {!string.IsNullOrEmpty(config)}");
    

客戶端密鑰已過期

錯誤AADSTS7000222: The provided client secret keys for app '{app-id}' are expired.

解決方法:

  1. 請前往 Microsoft Entra 系統管理中心 的應用程式註冊頁面。
  2. 請檢查「 憑證與秘密」>客戶端秘密下的到期日。
  3. 建立一個新的秘密並更新你的應用程式設定。
  4. 刪除入口網站的過期秘密。

設定中找不到金鑰

症狀: 應用程式拋出 a NullReferenceException 或因秘密值為 null而無法驗證 。

可能的原因:

  • 使用者密碼或機密尚未初始化於專案。
  • 環境變數名稱與預期的配置路徑不符。
  • 金鑰保存庫 並未被設定為設定來源。
  • 該應用程式運行在非開發環境,使用者秘密未被載入。

解決方法:

  1. 驗證使用者秘密是否已初始化,方法是檢查您的UserSecretsId 檔案中是否存在.csproj
  2. 驗證秘密是否已設定,請執行 dotnet user-secrets list
  3. 檢查設定路徑是否完全一致: AzureAd:ClientCredentials:0:ClientSecret
  4. 若在開發環境外執行,請確保有適當的設定來源(環境變數或 金鑰保存庫)。