使用 Microsoft.Identity.Web 設定無憑證認證。

本文將教你如何設定無憑證認證,讓你的應用程式能以 Microsoft Entra ID 進行認證,而不必管理憑證或用戶端秘密。 您的應用程式使用由 Azure 管理身份(Managed Identity)支持的聯邦身份憑證(Federated Identity Credential,FIC)來取得憑證,這消除了憑證輪替、減少秘密擴散,並簡化了 Azure 的部署。

Microsoft。Identity.Web 支援透過 SignedAssertionFromManagedIdentity 憑證來源類型進行無憑證認證,該格式可於版本 2.12.0 及以上版本提供。


了解無憑證認證

本節說明無憑證認證的運作方式及何時使用。

傳統上,機密客戶端應用程式透過呈現客戶端秘密或憑證來向 Microsoft Entra ID 證明其身份。 這兩種方法都需要你管理憑證生命週期——在秘密到期前輪替、更新憑證,並安全儲存。

聯邦身份憑證(FIC)改變了這種模式。 使用 FIC 時,你會設定應用程式註冊與管理身份之間的信任關係。 當你的應用程式需要認證時:

  1. Microsoft.Identity.Web 會向 Azure 主機上的受控身分識別端點請求一個存取權杖。
  2. 函式庫使用 Managed Identity 令牌作為簽署斷言,與 Microsoft Entra ID 進行認證。
  3. Microsoft Entra ID 會驗證已簽署的斷言,對照應用程式註冊時的聯邦憑證設定。
  4. Microsoft Entra ID 會為所請求的資源發出一個存取權杖。

結果是完全無需憑證的部署,配置、程式碼或環境變數中不存在秘密或憑證。

選擇正確的認證方式

下表幫助你判斷何時是無憑證認證的正確選擇。

Scenario 建議的方法
App 運行在 Azure 上,而你想要零憑證管理 FIC 無憑證
應用程式可在 Azure 上運行,但需要支援本地備援 以FIC為主要的憑證憑證
應用程式可在 Azure 外部執行(本地部署,其他雲端) 憑證或用戶端秘密
在本地機器上的開發與測試 用戶端秘密或本地商店的憑證

先決條件

開始前請確認你擁有以下資源與工具:

  • Azure訂閱。 如果您沒有訂用帳戶,請建立免費帳戶。
  • 在 Microsoft Entra ID 中註冊一個應用程式,並且有你情境所需的 API 權限。
  • Azure 中的 管理身份——可以是系統指派在你的計算資源上,或是獨立的使用者指派管理身份。
  • Microsoft。Identity.Web 版本 2.12.0 或更新版本安裝在您的專案中。
  • 支援管理身份的 Azure 計算資源,例如 Azure App 服務、Azure Kubernetes Service (AKS)、Azure 容器應用程式 或 Azure 虛擬機器。

步驟 1:建立或識別管理身份

你可以使用系統指派或使用者指派的管理身份。 如果你還沒建立一個,請依照你的情境指示操作。

選項A:使用系統指派的管理身份

系統指派的管理身份與 Azure 資源的生命週期綁定。 當你在像 App Service 這類資源上啟用系統指派的身份時,Azure 會自動建立一個身份。

  1. 在 Azure 入口網站,導航到運算資源(例如 App 服務)。
  2. 從左側導覽選單選擇「身份」。
  3. 在 [系統指派] 索引標籤上,將 [狀態] 設定為 [開啟]。
  4. 選擇 儲存 並確認動作。
  5. 建立身份後,複製 物件(主體)ID。 在設定聯邦憑證時,你需要這個值。

選項 B:建立使用者指派的管理身份

使用者指派的管理身份是獨立的 Azure 資源,你可以指派給一個或多個運算資源。

  1. 在 Azure 入口網站 中,搜尋 Managed Identities 並選擇它。
  2. 選取 ,創建。
  3. 選擇您的 訂閱、 資源群組、 區域,並輸入該身份的 名稱 。
  4. 選擇檢視並建立,然後選擇建立。
  5. 部署完成後,開啟新的管理身份資源。
  6. 從概覽頁面複製客戶 ID。 你需要這個數值來做應用程式設定。

步驟 2:在 Azure 入口中設定聯邦身份憑證

聯邦身份憑證(Federated Identity Credential)建立了應用程式註冊與管理身份之間的信任關係。 請依照以下步驟來建立一個:

  1. 在Azure 入口網站,前往Microsoft Entra ID>應用程式註冊。

  2. 選擇你應用程式所使用的應用程式註冊方式。

  3. 在左側導覽選單中,選擇 「憑證與秘密」。

  4. 選取同盟認證索引標籤。

  5. 選取新增認證。

  6. 在 聯邦憑證情境下,選擇 「客戶管理金鑰 」或 「其他發行者 」(可選選項依據你的入口網站版本而定)。

  7. 設定下列欄位:

    領域 價值
    簽發者 https://login.microsoftonline.com/{tenant-id}/v2.0 — 將{tenant-id}替換為您的Microsoft Entra租戶ID。
    主體標識碼 管理身份的 物件(主體)ID 。 關於系統指派項目的資訊,請在資源的識別頁面尋找。 關於使用者指派,請在管理身份的總覽頁面上找到 Principal ID 下的此資訊。
    名稱 例如,一個描述性名稱 fic-managed-identity-prod。
    觀眾 api://AzureADTokenExchange (預設值)。
  8. 選取 ,然後新增。

這很重要

主體識別碼必須與受管理身份的物件(主體)ID 完全相符。 不匹配會導致驗證失敗並產生 AADSTS70021 錯誤。

使用 Azure CLI 設定聯邦身份驗證憑證

或者,也可以用 Azure CLI 建立聯邦憑證。 以下指令會在你的應用程式註冊上建立一個憑證:

az ad app federated-credential create \
    --id <app-object-id> \
    --parameters '{
        "name": "fic-managed-identity-prod",
        "issuer": "https://login.microsoftonline.com/<tenant-id>/v2.0",
        "subject": "<managed-identity-principal-id>",
        "audiences": ["api://AzureADTokenExchange"],
        "description": "FIC for production managed identity"
    }'

依據 Azure 服務的發行者 URL

聯邦憑證中的發行者網址取決於託管你應用程式的 Azure 服務:

Azure 服務 簽發者網址
Azure App 服務 / Azure Functions https://login.microsoftonline.com/{tenant-id}/v2.0
Azure 容器應用程式 https://login.microsoftonline.com/{tenant-id}/v2.0
Azure Kubernetes Service (AKS) 你的叢集的 OIDC 發行者 URL(請使用 az aks show --query oidcIssuerProfile.issuerUrl 來檢索)
Azure 虛擬機器 https://login.microsoftonline.com/{tenant-id}/v2.0

主體識別格式

主體識別碼的格式取決於管理身份類型:

系統指派的受管理身份 — 使用資源 身份頁面中的 物件(主體)ID。 這是一個 GUID 值,例如 a1b2c3d4-e5f6-7890-abcd-ef1234567890。

使用者指派的管理身份 — 使用管理身份資源的概覽頁面中的主體 ID(亦稱為物件 ID)。 這也是一個 GUID 值。

備註

對於具有工作負載身份的 AKS,主體識別碼使用不同的格式: system:serviceaccount:{namespace}:{service-account-name}。 這個數值必須與你的 Pod 所使用的 Kubernetes 服務帳號相符。


步驟 3:設定您的應用程式

更新 appsettings.json

把該 ClientCredentials 區塊加入你的 AzureAd 設定。 將 SourceType 設定為 SignedAssertionFromManagedIdentity:

用於使用者指派的受控身分識別

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

取代下列預留位置:

Placeholder 說明
YOUR_TENANT_ID 你的 Microsoft Entra 租戶 ID。
YOUR_CLIENT_ID 你應用程式註冊時的應用程式(用戶端)ID。
USER_ASSIGNED_MSI_CLIENT_ID 使用者指派的管理身份的用戶端 ID(來自該身份的概覽頁面)。

系統指派的管理身份

當你使用系統指派的管理身份時,省略該 ManagedIdentityClientId 屬性。 Microsoft。Identity.Web 會自動使用主機系統指定的身份:

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

在 Program.cs 中註冊服務

啟動設定不需要特別的程式碼變更。 標準的 Microsoft。Identity.Web 註冊方法會自動讀取 ClientCredentials 區段。

以下範例為登入使用者並呼叫下游 API 的網頁應用程式註冊認證:

// For a web app that signs in users and calls downstream APIs
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
    .EnableTokenAcquisitionToCallDownstreamApi()
    .AddInMemoryTokenCaches();

以下範例註冊了網路 API 的身份驗證,這些 API 會呼叫下游 API。

// For a web API that calls downstream APIs
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"))
    .EnableTokenAcquisitionToCallDownstreamApi()
    .AddInMemoryTokenCaches();

以下範例是在無使用者互動的情況下,為守護程式應用程式登錄認證:

// For a daemon application (no user interaction)
builder.Services.AddAuthentication()
    .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));

builder.Services.AddTokenAcquisition()
    .AddInMemoryTokenCaches();

Microsoft。Identity.Web 偵測 SignedAssertionFromManagedIdentity 來源類型,並透明處理憑證交換。


比較系統指派與使用者指派的管理身份

選擇最適合你架構的管理身份類型。 以下章節將概述這些取捨。

系統指派的受管理身份識別

系統指派的身份會隨著該 Azure 資源自動建立和刪除。

優點:

  • 無需管理獨立資源——身份生命週期與計算資源相符。
  • 單一資源部署的設定更簡單。
  • 配置上不需要 ManagedIdentityClientId 。

考量因素:

  • 你不能在多個資源間共享身份。
  • 如果您刪除並重新建立資源,身份會改變——您必須更新聯邦身份憑證(Federated Identity Credential)。

最佳用途: 單一實例部署,其中一個計算資源對應一個應用程式註冊。

使用者指派的受控識別

使用者指派身份是一個獨立的 Azure 資源,擁有自己的生命週期。

優點:

  • 在多個計算資源(例如,不同區域的多個 App Service 實例)中共用單一身份。
  • 身份持續存在,獨立於計算資源的生命週期。
  • 在部署運算資源前,先預先建立並設定。

考量因素:

  • 額外需要管理的 Azure 資源。
  • 你必須在設定中指定 ManagedIdentityClientId。

最佳用途: 多實例或多區域部署、藍綠部署模式,以及經常重建運算資源的情境。


部署到 Azure 計算服務

設定好應用程式後,部署到支援管理身份的 Azure 運算服務。

Azure App 服務

  1. 在您的應用程式服務上啟用管理身份(見 步驟 1)。

  2. 用你偏好的方法(Visual Studio、Azure CLI、GitHub Actions)將你的應用程式部署到 App Service。

  3. 確保你部署的設定中,該 AzureAd 區塊與 步驟 3 的設定相符。

  4. 如果你使用使用者指派的管理身份,請將其指派給應用程式服務:

    az webapp identity assign \
      --resource-group <resource-group> \
      --name <app-service-name> \
      --identities <managed-identity-resource-id>
    
  5. 重新啟動 App Service 以取得身份指派。

Azure Kubernetes service (AKS)

對於 AKS,請使用 Workload identity 將 Kubernetes 服務帳號與 Managed Identity 關聯。 完成下列步驟:

  1. 在您的 AKS 叢集上啟用工作負載識別功能:

    az aks update \
      --resource-group <resource-group> \
      --name <aks-cluster-name> \
      --enable-oidc-issuer \
      --enable-workload-identity
    
  2. 建立一個以管理身份(Managed Identity)客戶端 ID 標註的 Kubernetes 服務帳號:

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: my-app-sa
      namespace: default
      annotations:
        azure.workload.identity/client-id: "<USER_ASSIGNED_MSI_CLIENT_ID>"
    
  3. 建立一個聯邦憑證,將 AKS OIDC 發行者與管理身份連結。

  4. 設定 pod 以使用服務帳戶:

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-app
      namespace: default
      labels:
        azure.workload.identity/use: "true"
    spec:
      serviceAccountName: my-app-sa
      containers:
        - name: my-app
          image: <your-container-image>
    
  5. 部署艙。 工作負載身份 webhook 注入受控身份憑證端點所需的環境變數。

Azure 容器應用程式

  1. 建立或更新您的容器應用程式,使用管理身份:

    az containerapp identity assign \
      --resource-group <resource-group> \
      --name <container-app-name> \
      --user-assigned <managed-identity-resource-id>
    
  2. 用適當的 AzureAd 設定部署你的容器映像。

  3. 管理身份憑證端點會自動在容器內開放。


從憑證遷移到無憑證認證

如果您的應用程式目前使用憑證式認證,您可以以最小的設定變更遷移至無憑證認證。

完成遷移步驟

  1. 為您的Azure計算資源建立管理身份(參見 步驟 1)。

  2. 在您的應用程式註冊中新增聯邦身份憑證(Federated Identity Credential)(見步驟2)。

  3. 更新你的設定 ,加入 SignedAssertionFromManagedIdentity 這個憑證。 你可以保留現有的憑證憑證作為遷移時的備用:

    {
      "AzureAd": {
        "Instance": "https://login.microsoftonline.com/",
        "TenantId": "YOUR_TENANT_ID",
        "ClientId": "YOUR_CLIENT_ID",
        "ClientCredentials": [
          {
            "SourceType": "SignedAssertionFromManagedIdentity",
            "ManagedIdentityClientId": "USER_ASSIGNED_MSI_CLIENT_ID"
          },
          {
            "SourceType": "KeyVault",
            "KeyVaultUrl": "https://your-keyvault.vault.azure.net",
            "KeyVaultCertificateName": "your-cert-name"
          }
        ]
      }
    }
    

    Microsoft.Identity.Web 依序嘗試憑證來源。 在 Azure 上執行時,第一個憑證(SignedAssertionFromManagedIdentity)成功。 若失敗(例如在本地開發期間),函式庫會退回到憑證。

  4. 在應用到生產環境前,先在暫存環境中部署並驗證。

  5. 在確認無憑證認證在生產環境中正常運作後,請從設定中移除憑證。

  6. 刪除Azure Key Vault的憑證,當不需要時再刪除應用程式註冊。

比較前後配置

以下範例展示了從憑證驗證到無憑證認證的設定變更。

之前(基於證書的):

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

之後(無證書):

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

解決常見錯誤

請參考以下指引來診斷並解決無憑證認證的問題。

AADSTS70021:未找到匹配的聯邦身份紀錄

原因: 聯邦身份憑證中的主體識別碼與管理身份的物件(主體)ID 不符。

解決方法:

  1. 在 Azure 入口網站中,前往受控身分識別資源,從 Overview 頁面複製 Principal ID (也稱為物件 ID)。
  2. 前往您的應用程式註冊 >憑證與祕密>聯合憑證。
  3. 請確認 主體識別 欄位與主體 ID 完全一致。
  4. 如果數值不符,刪除憑證並用正確的主體識別碼重新建立。

AADSTS700024:用戶聲明不在其有效時間範圍內

原因: 用作簽署斷言的管理身份憑證已過期或系統時鐘偏斜。

解決方法:

  • 請確認你 Azure 資源的系統時鐘是否準確。
  • 重新啟動應用程式以強制執行新的管理身份令牌請求。
  • 如果你在容器中執行,請確保容器的時鐘與主機同步。

ManagedIdentityException:管理身份端點不可用

Cause: 應用程式無法存取Azure實例元資料服務(IMDS)或受管身份憑證端點。

解決方法:

  • 確認該應用程式是否運行在支援管理身份的 Azure 運算資源上。
  • 確認管理身份是否已啟用並指派給計算資源。
  • 對於 AKS,請確認工作負載身份 webhook 正在運行,並檢查 pod 是否具備正確的服務帳號註釋。
  • 對於地方開發來說,這種錯誤是可以預期的。 使用備用憑證來源(參見 遷移步驟)。

AADSTS700016:應用程式未在目錄中找到

原因: 你設定中的 App ClientId 與指定租戶的有效應用程式註冊不符。

解決方法:

  • 確認與 ClientId 你應用程式註冊時的 應用程式(用戶端)ID 相符。
  • 確認 TenantId 是否與該應用程式註冊的租戶相符。

啟用偵錯記錄

原因: 憑證來源順序或設定不符可能導致函式庫跳過 FIC 憑證。

解決方法:

  1. 啟用 Microsoft.Identity.Web 的記錄功能,以查看詳細的代幣取得步驟。 以下程式碼配置了身份函式庫的除錯層日誌記錄:

    builder.Services.AddLogging(logging =>
    {
        logging.AddConsole();
        logging.SetMinimumLevel(LogLevel.Debug);
        logging.AddFilter("Microsoft.Identity", LogLevel.Debug);
    });
    
  2. 檢查日誌,以了解函式庫嘗試使用哪一個憑證來源並查看是否有任何錯誤回傳。

使用者指派的管理身份未被接收

原因: 當多個使用者指派的受管理身份被指派給一個運算資源時,若未指定 ManagedIdentityClientId,函式庫可能會使用錯誤的身份。

解決方法:

  • 使用使用者指派的管理身份時,務必指定該 ManagedIdentityClientId 屬性。
  • 確認客戶端 ID 是否與你設定的聯邦身份憑證(Federated Identity Credential)相符。

檢視安全效益

FIC的無憑證認證相較於傳統憑證方式具有顯著的安全優勢:

沒有秘密可洩漏

因為你的設定或部署產物中不存在憑證檔案、PFX 密碼或用戶端秘密,攻擊者無法擷取任何資料。 即使攻擊者取得你的設定檔讀取權限,他們也無法從 Azure 外部冒充你的應用程式。

沒有資格輪替

管理身份憑證壽命短暫,並由 Azure 平台自動刷新。 你不需要實施輪替排程、監控到期日,或在不同部署間協調憑證更新。

降低攻擊面

管理身份憑證端點只能從該身份所指派的特定 Azure 資源存取。 攻擊者無法使用來自其他主機、網路或雲端環境的憑證。

合規簡化

若沒有長期認證,就能消除幾類合規疑慮:

  • 沒有儲存在原始碼控制、環境變數或設定檔中的秘密。
  • 沒有關鍵資料需要審核、輪換或撤銷。
  • 沒有憑證基礎架構(CA、續約流程)需要維護。

深層防禦

將無憑證認證與其他 Azure 安全功能結合,以實現分層保護:

  • Azure RBAC:控制哪些身份可以存取哪些資源。
  • 條件存取:根據身份風險、位置及裝置狀態套用政策。
  • 私人端點:限制網路對Azure資源的存取。
  • 適用於雲端的 Microsoft Defender:監控可疑的認證模式。