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

當您有需要存取資源的應用程式或腳本時,您可以設定應用程式的身分識別,並使用自己的認證驗證應用程式。 此身分識別稱為服務主體。 此方法可讓您:

  • 將許可權指派給與您自己的許可權不同的應用程式身分識別。 一般而言,這些許可權僅限於應用程式需要執行的確切作業。
  • 在執行自動腳本時,請使用憑證進行驗證。

重要

請考慮針對應用程式身分識別使用 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 中建立應用程式,並將服務主體指派給角色。

檢查您的帳戶是否有適當的許可權,最簡單的方式是透過入口網站。 請參閱 檢查必要的許可權

將應用程式指派給角色

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

您可以在訂用帳戶、資源群組或資源層級設定範圍。 許可權會繼承至較低層級的範圍。 例如,將應用程式新增至資源群組的 讀取者 角色表示它可以讀取資源群組及其包含的任何資源。 若要允許應用程式執行重新開機、啟動和停止實例等動作,請選取參與者 角色。

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

下列範例涵蓋簡單的案例。 它會使用 New-AzADServicePrincipal 建立具有自我簽署憑證的服務主體,並使用 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 參數,將角色指派限定為特定資源群組 。 您也可以使用 ResourceType ResourceName 參數來限定特定資源的範圍。

如果您沒有 Windows 10 或 Windows Server 2016 ,請從 PKI 解決方案下載 New-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 識別碼的實例。

$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 識別碼的實例。

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 應用程式的認證,可能是因為安全性洩露或認證到期,請使用 Remove-AzADAppCredential New-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'」。 - 當您的帳戶沒有足夠的許可權將角色指派給身分識別時,您會看到此錯誤。 要求訂用帳戶管理員將您新增至使用者存取管理員istrator 角色。

下一步