分享方式:


使用 Azure PowerShell 建立含有憑證的服務主體

當您有 App 或指令碼需要存取資源時,可以設定 App 的身分識別,並使用 App 自己的認證進行驗證。 此身分識別就是所謂的服務主體。 這種方法可讓您︰

  • 將權限指派給不同於您自己權限的 App 身分識別。 一般而言,這些權限只會限制為 App 必須執行的確切權限。
  • 使用憑證在執行無人看管的指令碼時進行驗證。

重要

請考慮針對您的應用程式的身分識別使用 Azure 資源受控識別,而不是建立服務主體。 如果您的程式碼在支援受控識別的服務上執行,以及存取支援 Microsoft Entra 驗證的資源,則受控識別是較適合您的選項。 若要深入了解 Azure 資源受控識別 (包括目前支援哪些服務),請參閱什麼是 Azure 資源受控識別?

本文會示範如何建立可透過憑證進行驗證的服務主體。 若要使用密碼設定服務主體,請參閱使用 Azure PowerShell 建立 Azure 服務主體

您必須擁有最新版的 PowerShell 以符合本文需求。

注意

建議您使用 Azure Az PowerShell 模組來與 Azure 互動。 請參閱安裝 Azure PowerShell 以開始使用。 若要了解如何移轉至 Az PowerShell 模組,請參閱將 Azure PowerShell 從 AzureRM 移轉至 Az

所需的權限

若要完成本文,您必須在 Microsoft Entra ID 和 Azure 訂用帳戶中擁有足夠的權限。 具體而言,您必須能夠在 Microsoft Entra ID 中建立應用程式,並將服務主體指派給角色。

檢查您的帳戶是否有適當的權限,最簡單的方式是透過 Microsoft Entra 系統管理中心。

指派角色給應用程式

若要存取您的訂用帳戶中的資源,您必須將應用程式指派給角色。 決定哪個角色為應用程式提供適當的權限。 若要深入瞭解可用的角色,請參閱 Azure 內建角色

您可以在訂用帳戶、資源群組或資源層級設定範圍。 權限會繼承至較低層級的範圍。 例如,為資源群組的「讀取者」角色新增應用程式,代表該角色可以讀取資源群組及其所包含的任何資源。 若要允許應用程式執行動作 (例如,重新啟動、開始和停止執行個體),請選取 [參與者] 角色。

使用自我簽署憑證建立服務主體

下列範例涵蓋簡單的案例。 它會使用 New-AzAD​服務主體來 建立具有自我簽署憑證的服務主體,並使用 New-AzRoleAssignment讀取者 角色指派給服務主體。 角色指派的範圍僅限於您目前所選的 Azure 訂用帳戶。 若要選取不同的訂用帳戶,請使用 Set-AzContext

注意

PowerShell Core 目前不支援 New-SelfSignedCertificate Cmdlet 和 PKI 模組。

$cert = New-SelfSignedCertificate -CertStoreLocation "cert:\CurrentUser\My" `
  -Subject "CN=exampleappScriptCert" `
  -KeySpec KeyExchange
$keyValue = [System.Convert]::ToBase64String($cert.GetRawCertData())

$sp = New-AzADServicePrincipal -DisplayName exampleapp `
  -CertValue $keyValue `
  -EndDate $cert.NotAfter `
  -StartDate $cert.NotBefore
Sleep 20
New-AzRoleAssignment -RoleDefinitionName Reader -ServicePrincipalName $sp.AppId

此範例會休眠 20 秒,讓新的服務主體在 Microsoft Entra ID 中傳播一段時間。 如果您的指令碼等候時間不夠長,您會看到錯誤,指出「主體 {ID} 不存在於目錄 {DIR-ID} 中。」若要解決這個錯誤,請稍待片刻後,再次執行 New-AzRoleAssignment 命令。

您可以使用 ResourceGroupName 參數將角色指派的範圍限定為特定的資源群組。 您也可以使用 ResourceTypeResourceName 將範圍限制為特定的資源。

如果您沒有Windows 10 或 Windows Server 2016,請從 PKI 解決方案下載 SelfSignedCertificateEx Cmdlet。 將其內容解壓縮,並匯入您需要的 Cmdlet。

# Only run if you could not use New-SelfSignedCertificate
Import-Module -Name c:\ExtractedModule\New-SelfSignedCertificateEx.ps1

在指令碼中,取代下列兩行來產生憑證。

New-SelfSignedCertificateEx -StoreLocation CurrentUser `
  -Subject "CN=exampleapp" `
  -KeySpec "Exchange" `
  -FriendlyName "exampleapp"
$cert = Get-ChildItem -path Cert:\CurrentUser\my | where {$PSitem.Subject -eq 'CN=exampleapp' }

透過自動化的 PowerShell 指令碼提供憑證

每當您以服務主體的形式登入時,請提供 AD 應用程式目錄的租用戶識別碼。 租用戶是 Microsoft Entra ID 的實例。

$TenantId = (Get-AzSubscription -SubscriptionName "Contoso Default").TenantId
$ApplicationId = (Get-AzADApplication -DisplayNameStartWith exampleapp).AppId

$Thumbprint = (Get-ChildItem cert:\CurrentUser\My\ | Where-Object {$_.Subject -eq "CN=exampleappScriptCert" }).Thumbprint
Connect-AzAccount -ServicePrincipal `
  -CertificateThumbprint $Thumbprint `
  -ApplicationId $ApplicationId `
  -TenantId $TenantId

使用憑證授權中心的憑證來建立服務主體

下列範例使用憑證授權中心所發行的憑證來建立服務主體。 指派範圍僅限於指定的 Azure 訂用帳戶。 將服務主體新增至 [讀取者] 角色。 如果角色指派期間發生錯誤,則指派會重試。

Param (
 [Parameter(Mandatory=$true)]
 [String] $ApplicationDisplayName,

 [Parameter(Mandatory=$true)]
 [String] $SubscriptionId,

 [Parameter(Mandatory=$true)]
 [String] $CertPath,

 [Parameter(Mandatory=$true)]
 [String] $CertPlainPassword
 )

 Connect-AzAccount
 Import-Module Az.Resources
 Set-AzContext -Subscription $SubscriptionId

 $CertPassword = ConvertTo-SecureString $CertPlainPassword -AsPlainText -Force

 $PFXCert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2 -ArgumentList @($CertPath, $CertPassword)
 $KeyValue = [System.Convert]::ToBase64String($PFXCert.GetRawCertData())

 $ServicePrincipal = New-AzADServicePrincipal -DisplayName $ApplicationDisplayName
 New-AzADSpCredential -ObjectId $ServicePrincipal.Id -CertValue $KeyValue -StartDate $PFXCert.NotBefore -EndDate $PFXCert.NotAfter
 Get-AzADServicePrincipal -ObjectId $ServicePrincipal.Id 

 $NewRole = $null
 $Retries = 0;
 While ($NewRole -eq $null -and $Retries -le 6)
 {
    # Sleep here for a few seconds to allow the service principal application to become active (should only take a couple of seconds normally)
    Sleep 15
    New-AzRoleAssignment -RoleDefinitionName Reader -ServicePrincipalName $ServicePrincipal.AppId | Write-Verbose -ErrorAction SilentlyContinue
    $NewRole = Get-AzRoleAssignment -ObjectId $ServicePrincipal.Id -ErrorAction SilentlyContinue
    $Retries++;
 }

 $NewRole

透過自動化的 PowerShell 指令碼提供憑證

每當您以服務主體的形式登入時,請提供 AD 應用程式目錄的租用戶識別碼。 租用戶是 Microsoft Entra ID 的實例。

Param (

 [Parameter(Mandatory=$true)]
 [String] $CertPath,

 [Parameter(Mandatory=$true)]
 [String] $CertPlainPassword,

 [Parameter(Mandatory=$true)]
 [String] $ApplicationId,

 [Parameter(Mandatory=$true)]
 [String] $TenantId
 )

 $CertPassword = ConvertTo-SecureString $CertPlainPassword -AsPlainText -Force
 $PFXCert = New-Object `
  -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2 `
  -ArgumentList @($CertPath, $CertPassword)
 $Thumbprint = $PFXCert.Thumbprint

 Connect-AzAccount -ServicePrincipal `
  -CertificateThumbprint $Thumbprint `
  -ApplicationId $ApplicationId `
  -TenantId $TenantId

應用程式識別碼和租用戶識別碼不區分大小寫,因此您可以直接將它們內嵌在您的指令碼中。 如果您要擷取租用戶識別碼,請使用︰

(Get-AzSubscription -SubscriptionName "Contoso Default").TenantId

如果您要擷取應用程式識別碼,請使用︰

(Get-AzADApplication -DisplayNameStartWith {display-name}).AppId

管理認證

若要變更 AD App 的認證,不管是因為安全性危害或認證過期,請使用 Remove-AzADAppCredentialNew-AzADAppCredential Cmdlet。

若要移除應用程式的所有認證,使用︰

Get-AzADApplication -DisplayName exampleapp | Remove-AzADAppCredential

若要新增憑證值,請建立自我簽署的憑證,如本文中所述。 然後,使用︰

Get-AzADApplication -DisplayName exampleapp | New-AzADAppCredential `
  -CertValue $keyValue `
  -EndDate $cert.NotAfter `
  -StartDate $cert.NotBefore

偵錯

建立服務主體時,您可能會遇到下列錯誤︰

  • 「Authentication_Unauthorized」「內容中找不到訂用帳戶。」 - 當您的帳戶沒有向 Microsoft Entra ID 註冊應用程式的 必要權限 時,就會看到此錯誤。 一般而言,當您的 Microsoft Entra ID 中只有系統管理員使用者可以註冊應用程式,且您的帳戶不是系統管理員時,就會看到此錯誤。要求系統管理員將您指派給系統管理員角色,或是讓使用者註冊應用程式。

  • 您的帳戶「沒有在範圍 '/subscriptions/{guid}' 中執行 'Microsoft.Authorization/roleAssignments/write' 動作的權限。」 - 當您的帳戶沒有足夠權限可將角色指派給身分識別時,您就會看到此錯誤。 要求訂用帳戶管理員將您新增至「使用者存取系統管理員」角色。

下一步