從內部部署裝載的 .NET 應用程式向 Azure 資源進行驗證

裝載於 Azure 外部的應用程式 (例如內部部署或第三方資料中心) 應該使用應用程式服務主體,在存取 Azure 資源時向 Azure 進行驗證。 系統會在 Azure 中使用應用程式註冊程序來建立應用程式服務主體物件。 建立應用程式服務主體時,將會為您的應用程式產生用戶端識別碼和用戶端密碼。 接著,用戶端識別碼、用戶端密碼和租用戶識別碼會儲存在環境變數中,讓 Azure SDK for .NET 用來在執行階段向 Azure 驗證您的應用程式。

應該為裝載應用程式所在的每個環境建立不同的應用程式註冊。 這可讓環境特定資源權限針對每個服務主體進行設定,並確定部署到某個環境的應用程式不會與屬於另一個環境的 Azure 資源交談。

1:在 Azure 中註冊應用程式

您可以使用 Azure 入口網站或 Azure CLI 向 Azure 註冊應用程式。

登入 Azure 入口網站並遵循下列步驟。

指示 Screenshot
在 Azure 入口網站中:
  1. 在 Azure 入口網站頂端的搜尋列中輸入應用程式註冊
  2. 在搜尋列下方出現的功能表上的 [服務] 標題下,選取標有 [應用程式註冊] 的項目。
A screenshot showing how to use the top search bar in the Azure portal to find and navigate to the App registrations page.
在 [應用程式註冊] 頁面上,選取 [+ 新增註冊] A screenshot showing the location of the New registration button in the App registrations page.
在 [註冊應用程式] 頁面中,如下所示填妥表單。
  1. 名稱 → 輸入 Azure 中應用程式註冊的名稱。 建議此名稱包括為其進行應用程式註冊的應用程式名稱和環境 (測試、實際執行)。
  2. 支援的帳戶類型僅限此組織目錄中的帳戶
選取 [註冊] 來註冊您的應用程式,並建立應用程式服務主體。
A screenshot showing how to fill out the Register an application page by giving the app a name and specifying supported account types as accounts in this organizational directory only.
在您應用程式的 [應用程式註冊] 頁面中:
  1. 應用程式 (用戶端) 識別碼 → 這是應用程式要用來於本機開發期間存取 Azure 的應用程式識別碼。 請將此值複製到文字編輯器內的暫存位置,後續步驟還會用到。
  2. 目錄 (租用戶) 識別碼 → 此值也會於應用程式向 Azure 驗證時派上用場。 請將此值複製到文字編輯器內的暫存位置,後續步驟同樣還會用到。
  3. 用戶端認證 → 您必須為應用程式設定用戶端認證,之後應用程式才能向 Azure 驗證並使用 Azure 服務。 請選取 [新增憑證或祕密],將憑證新增至您的應用程式。
A screenshot of the App registration page after the app registration has been completed. This screenshot shows the location of the application ID and tenant ID which will be needed in a future step. It also shows the location of the link to use to add an application secret for the app.
在 [憑證及祕密] 頁面中,選取 [+ 新增用戶端密碼] A screenshot showing the location of the link to use to create a new client secret on the certificates and secrets page.
[新增用戶端密碼] 對話方塊會在頁面右側彈出。 此對話方塊會顯示:
  1. 說明 → 輸入 Current 的值。
  2. 到期 → 選取 24 個月 的值。
選取 [新增] 新增祕密。

重要: 在祕密到期日之前,在您的行事曆中設定提醒。如此,您可以在此祕密到期前新增新的祕密,並在此祕密到期前更新您的應用程式,避免應用程式中的服務中斷。
A screenshot showing the page where a new client secret is added for the application service principal created by the app registration process.
在 [憑證及秘密] 頁面中,系統會顯示用戶端密碼的值。

請將此值複製到文字編輯器內的暫存位置,後續步驟還會用到。

重要:這是您唯一會看到此值的時間。離開或重新整理此頁面之後,您將無法再次看到此值。 您可以新增其他用戶端密碼而不將此密碼設為無效,但您不會再次看到此值。
A screenshot showing the page with the generated client secret.

2:將角色指派給應用程式服務主體

接著,您必須決定應用程式針對哪些資源需要哪些角色 (權限),並將這些角色指派給應用程式。 角色可在資源、資源群組或訂閱範圍內獲派其他角色。 此範例會顯示如何在資源群組範圍內為服務主體指派角色,因為多數應用程式都會將所有 Azure 資源劃分在單一資源群組中。

指示 Screenshot
用 Azure 入口網站頂端的搜尋方塊,搜尋資源群組的名稱,藉此找出應用程式的資源群組。

選取對話方塊中 資源群組 標題下方的資源群組名稱,瀏覽至您的資源群組。
A screenshot showing how to use the top search box in the Azure portal to locate and navigate to the resource group you want to assign roles (permissions) to.
在資源群組分頁中,從左側功能表選取 存取控制 (IAM) A screenshot of the resource group page showing the location of the Access control (IAM) menu item.
存取控制 (IAM) 分頁上:
  1. 選取 [角色指派] 索引標籤。
  2. 從頂端功能表選取 [+ 新增],然後從產生的下拉功能表中選取 [新增角色指派]
A screenshot showing how to navigate to the role assignments tab and the location of the button used to add role assignments to a resource group.
新增角色指派 分頁列出所有可指派至資源群組之角色的清單。
  1. 請善用搜尋方塊,將清單篩選為更易於管理的大小。 此範例顯示如何針對儲存體 Blob 角色進行篩選。
  2. 選取您要指派的角色。
選取 [下一步] 前往下一個畫面。
A screenshot showing how to filter and select role assignments to be added to the resource group.
下一個 新增角色指派 分頁能讓您指定要指派角色的使用者。
  1. 選取 [存取權指派對象為] 下的 [使用者、群組或服務主體]
  2. 選取 [成員] 下的 [+ 選取成員]
對話方塊會在 Azure 入口網站的右側開啟。
A screenshot showing the radio button to select to assign a role to an Azure AD group and the link used to select the group to assign the role to.
在 [選取成員] 對話方塊進行下列設定:
  1. [選取] 文字輸入框可用來篩選訂閱中的使用者及群組清單。 如有需要,請輸入您為應用程式建立的服務主體前幾個字元來篩選清單。
  2. 選取與應用程式相關聯的服務主體。
選取對話方塊底部的 [選取] 來繼續。
A screenshot showing how to filter for and select the Azure AD group for the application in the Select members dialog box.
現在服務主體會在 [新增角色指派] 畫面上顯示為已選取。

選取 [檢閱 + 指派] 移至最終分頁,然後再次選取 [檢閱 + 指派] 完成此流程。
A screenshot showing the completed Add role assignment page and the location of the Review + assign button used to complete the process.

3:設定應用程式的環境變數

DefaultAzureCredential 物件會於執行階段在一組環境變數中尋找服務主體認證。 使用 .NET 時設定環境變數的方法有很多,視乎於使用的工具和環境而定。

無論您選擇哪一種方法,都需要在使用服務主體時設定下列環境變數。

  • AZURE_CLIENT_ID → 應用程式識別碼的值。
  • AZURE_TENANT_ID → 租用戶識別碼的值。
  • AZURE_CLIENT_SECRET → 為應用程式產生的密碼/認證。

如果您的應用程式裝載於 IIS 中,建議您為每個應用程式集區設定環境變數,以隔離應用程式之間的設定。

appcmd.exe set config -section:system.applicationHost/applicationPools /+"[name='Contoso'].environmentVariables.[name='ASPNETCORE_ENVIRONMENT',value='Production']" /commit:apphost
appcmd.exe set config -section:system.applicationHost/applicationPools /+"[name='Contoso'].environmentVariables.[name='AZURE_CLIENT_ID',value='00000000-0000-0000-0000-000000000000']" /commit:apphost
appcmd.exe set config -section:system.applicationHost/applicationPools /+"[name='Contoso'].environmentVariables.[name='AZURE_TENANT_ID',value='11111111-1111-1111-1111-111111111111']" /commit:apphost
appcmd.exe set config -section:system.applicationHost/applicationPools /+"[name='Contoso'].environmentVariables.[name='AZURE_CLIENT_SECRET',value='=abcdefghijklmnopqrstuvwxyz']" /commit:apphost

您也可以直接使用 applicationHost.config 檔案內的 applicationPools 元素來設定這些設定。

<applicationPools>
   <add name="CorePool" managedRuntimeVersion="v4.0" managedPipelineMode="Classic">
      <environmentVariables>
         <add name="ASPNETCORE_ENVIRONMENT" value="Development" />
         <add name="AZURE_CLIENT_ID" value="00000000-0000-0000-0000-000000000000" />
         <add name="AZURE_TENANT_ID" value="11111111-1111-1111-1111-111111111111" />
         <add name="AZURE_CLIENT_SECRET" value="=abcdefghijklmnopqrstuvwxyz" />
      </environmentVariables>
   </add>
</applicationPools>

4:在應用程式中實作 DefaultAzureCredential

DefaultAzureCredential 支援多種驗證方法,並會決定執行階段期間使用的驗證方法。 因此,您的應用程式可在相異的環境中使用不同的驗證方法,無須實作環境特定程式碼。

DefaultAzureCredential 尋找認證的順序和位置,可在 DefaultAzureCredential中找到。

為實作 DefaultAzureCredential,請先將 Azure.Identity 與選擇性的 Microsoft.Extensions.Azure 套件新增至您的應用程式。 您可透過命令列或 NuGet 套件管理員執行此動作。

在應用程式專案目錄中開啟您想要的終端環境,然後輸入下列命令。

dotnet add package Azure.Identity
dotnet add package Microsoft.Extensions.Azure

Azure 服務通常使用 SDK 的對應用戶端類別來存取。 這些類別和您自訂的服務都應在 Program.cs 檔案中註冊,使其可在應用程式中透過相依性插入來存取。 請依照下列步驟,在 Program.cs 內正確設定您的服務和 DefaultAzureCredential

  1. 用 Using 陳述式納入 Azure.IdentityMicrosoft.Extensions.Azure 命名空間。
  2. 用相關的協助程式方法註冊 Azure 服務。
  3. DefaultAzureCredential 物件的執行個體傳遞至 UseCredential 方法。

下列程式碼區段示範其中一種範例。

using Microsoft.Extensions.Azure;
using Azure.Identity;

// Inside of Program.cs
builder.Services.AddAzureClients(x =>
{
    x.AddBlobServiceClient(new Uri("https://<account-name>.blob.core.windows.net"));
    x.UseCredential(new DefaultAzureCredential());
});

或者,您也可以更直接地在服務中使用 DefaultAzureCredential,而不求助於其他 Azure 註冊方法,如下所示。

using Azure.Identity;

// Inside of Program.cs
builder.Services.AddSingleton<BlobServiceClient>(x => 
    new BlobServiceClient(
        new Uri("https://<account-name>.blob.core.windows.net"),
        new DefaultAzureCredential()));

上述程式碼在本機開發期間於本機工作站上執行時,會尋找環境變數中的應用程式服務主體,或在 Visual Studio、VS Code、Azure CLI 或 Azure PowerShell 中尋找一組開發人員認證;任意者皆可於本機開發期間用來向 Azure 資源驗證應用程式。

部署至 Azure 時,這同一組程式碼也可向其他 Azure 資源驗證您的應用程式。 DefaultAzureCredential 可擷取環境設定與受控識別設定,以便自動向其他服務進行驗證。