使用 Azure CLI 來建立 Azure 服務主體

使用 Azure 服務的自動化工具應一律具有權限限制。 Azure 提供的服務主體,可替代以具有完整權限的使用者身分登入應用程式。

什麼是 Azure 服務主體?

Azure 服務主體是一種身分識別,建立目的是為了搭配應用程式、託管服務及自動化工具來存取 Azure 資源。 此存取會受限於指派給服務主體的角色,以便您控制可存取的資源,以及在哪個層級上存取。 基於安全理由,我們建議您一律搭配自動化工具使用服務主體,而不是讓服務主體透過使用者身分識別來登入。

本文說明如何使用 Azure CLI 建立、取得 Azure 服務主體的相關資訊,以及重設 Azure 服務主體的步驟。

1.建立服務主體

使用 az ad sp create-for-rbac 命令建立 Azure 服務主體。

appIdtenant 索引鍵會出現在 az ad sp create-for-rbac 的輸出中,並且用於服務主體驗證。 請記錄其值,但這些值可以隨時透過 az ad sp list 來擷取。

建立服務主體時,您可以選擇其所用的登入驗證類型。 Azure 服務主體有兩種類型的驗證可用:密碼型驗證和憑證型驗證。

警告

當您使用 az ad sp create-for-rbac 命令建立 Azure 服務主體時,輸出會包含您必須保護的認證。 請務必不要在程式碼中包含這些認證,或是將認證簽入原始檔控制中。 或者,如果可以使用,請考慮使用 受控識別 ,以避免需要使用認證。

若要降低遭入侵服務主體的風險,請指派更特定的角色,並將範圍縮小至資源或資源群組。 如需相關資訊,請參閱新增角色指派的步驟

密碼式驗證

使用密碼型驗證,系統會為您建立隨機密碼。 如果您未指定 --name 參數值,將會為您建立包含時間戳記的名稱。 您必須指定 --scopes ,因為這個值沒有預設值。 如果您想要的話,稍後可以使用 az role assignment create 來設定角色指派

# Create a service principal with required parameter
az ad sp create-for-rbac --scopes /subscriptions/mySubscriptionID

# Create a service principal for a resource group using a preferred name and role
az ad sp create-for-rbac --name myServicePrincipalName \
                         --role reader \
                         --scopes /subscriptions/mySubscriptionID/resourceGroups/myResourceGroupName

您也可以使用變數建立服務主體。

let "randomIdentifier=$RANDOM*$RANDOM"  
servicePrincipalName="msdocs-sp-$randomIdentifier"
roleName="azureRoleName"
subscriptionID=$(az account show --query id -o tsv)
# Verify the ID of the active subscription
echo "Using subscription ID $subscriptionID"
resourceGroup="myResourceGroupName"

echo "Creating SP for RBAC with name $servicePrincipalName, with role $roleName and in scopes /subscriptions/$subscriptionID/resourceGroups/$resourceGroup"
az ad sp create-for-rbac --name $servicePrincipalName --role $roleName --scopes /subscriptions/$subscriptionID/resourceGroups/$resourceGroup

搭配密碼驗證使用的服務主體輸出包含 password 索引鍵。 請確定您複製此值 - 無法擷取此值。 如果您遺失密碼,請重設服務主體認證

憑證式驗證

針對憑證式驗證,請使用 --cert 參數。 此參數需要您保留現有的憑證。 請確定使用此服務主體的任何工具皆可存取憑證的私密金鑰。 憑證應使用 ASCII 格式,例如 PEM、CER 或 DER。 將憑證傳遞為字串,或使用 @path 格式從檔案載入憑證。

注意

使用 PEM 檔案時,必須將 憑證 附加至檔案中的 私密金鑰

az ad sp create-for-rbac --name myServicePrincipalName \
                         --role roleName \
                         --scopes /subscriptions/mySubscriptionID/resourceGroups/myResourceGroupName \
                         --cert "-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----"
az ad sp create-for-rbac --name myServicePrincipalName \
                         --role roleName \
                         --scopes /subscriptions/mySubscriptionID/resourceGroups/myResourceGroupName \
                         --cert @/path/to/cert.pem

--keyvault您可以新增 參數,以在 Azure 金鑰保存庫中使用憑證。 在此案例中,--cert 值是憑證的名稱。

az ad sp create-for-rbac --name myServicePrincipalName \
                         --role roleName \
                         --scopes /subscriptions/mySubscriptionID/resourceGroups/myResourceGroupName \
                         --cert certificateName \
                         --keyvault vaultName

若要建立 自我簽署 憑證以進行驗證,請使用 --create-cert 參數:

az ad sp create-for-rbac --name myServicePrincipalName \
                         --role roleName \
                         --scopes /subscriptions/mySubscriptionID/resourceGroups/myResourceGroupName \
                         --create-cert

主控台輸出:

Creating a role assignment under the scopes of "/subscriptions/myId"
Please copy C:\myPath\myNewFile.pem to a safe place.
When you run 'az login', provide the file path in the --password parameter
{
  "appId": "myAppId",
  "displayName": "myDisplayName",
  "fileWithCertAndPrivateKey": "C:\\myPath\\myNewFile.pem",
  "name": "http://myName",
  "password": null,
  "tenant": "myTenantId"
}

新 PEM 檔案的內容:

-----BEGIN PRIVATE KEY-----
myPrivateKeyValue
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
myCertificateValue
-----END CERTIFICATE-----

注意

az ad sp create-for-rbac --create-cert 命令會建立服務主體和 PEM 檔案。 PEM 檔案包含格式正確的 私密金鑰憑證

--keyvault您可以新增 參數,將憑證儲存在 Azure 金鑰保存庫中。 使用 --keyvault 時, --cert 需要 參數。

az ad sp create-for-rbac --name myServicePrincipalName \
                         --role roleName \
                         --scopes /subscriptions/mySubscriptionID/resourceGroups/myResourceGroupName \
                         --create-cert \
                         --cert certificateName \
                         --keyvault vaultName

除非您將憑證儲存在 Key Vault,否則輸出會包含 fileWithCertAndPrivateKey 索引鍵。 此索引鍵的值會告訴您產生的憑證儲存在何處。 務必 將憑證複製到安全的位置,否則您會無法使用此服務主體來登入。

如果您無法存取憑證的私密金鑰,請重設服務主體認證

從金鑰保存庫擷取憑證

對於儲存在 金鑰保存庫 中的憑證,請使用az keyvault secret show擷取具有私密金鑰的憑證,並將其轉換成 PEM 檔案。 在金鑰保存庫中,憑證秘密的名稱與憑證名稱相同。

az keyvault secret download --file /path/to/cert.pfx --vault-name VaultName --name CertName --encoding base64
openssl pkcs12 -in cert.pfx -passin pass: -out cert.pem -nodes

2.取得現有的服務主體

租用戶中的服務主體清單,可以使用 az ad sp list 來擷取。 依預設,此命令會傳回您租用戶的前 100 個服務主體。 若要取得租使用者的所有服務主體,請使用 --all 參數。 取得此清單可能需要很長的時間,因此建議您使用下列其中一個參數來篩選清單:

  • --display-name 會要求服務主體的「前置詞」符合所提供的名稱。 服務主體的顯示名稱是建立期間使用 --name 參數所設定的值。 如果您未在服務主體建立期間設定 --name,則名稱前置詞會是 azure-cli-
  • --spn 會以確切的服務主體名稱比對進行篩選。 服務主體名稱一律以 https:// 開頭。 如果您用於 --name 的值不是 URI,則此值會是後面接著顯示名稱的 https://
  • --show-mine 會要求僅限已登入使用者建立的服務主體。
  • --filter 採用 OData 篩選,而且會執行「伺服器端」的篩選。 建議使用 CLI 的 --query 參數來篩選用戶端,以使用此方法。 若要深入了解 OData 篩選,請參閱用於篩選的 OData 運算式語法

傳回的服務主體物件資訊是詳細資訊。 若只要取得登入所需的資訊,請使用查詢字串 [].{id:appId, tenant:appOwnerTenantId}。 例如,若要取得由目前已登入使用者所建立的所有服務主體登入資訊:

az ad sp list --show-mine --query "[].{id:appId, tenant:appOwnerTenantId}"

重要

az ad sp listaz ad sp show 會取得使用者和租用戶,但不含任何驗證祕密「或」驗證方法。 您可以使用 az keyvault secret show 來擷取 Key Vault 中憑證的祕密,但預設不會儲存任何其他祕密。 如果您忘記驗證方法或祕密,請重設服務主體認證

3.管理服務主體角色

Azure CLI 使用下列命令來管理角色指派:

參與者 角色具有讀取和寫入至 Azure 帳戶的完整權限。 讀者 角色的權限較為侷限,僅有唯讀存取權。 如需角色型存取控制 (RBAC) 和角色的詳細資訊,請參閱 RBAC:內建角色

此範例會新增 讀者 角色,並移除 參與者 角色:

az role assignment create --assignee appID \
                          --role Reader \
                          --scope /subscriptions/mySubscriptionID/resourceGroups/myResourceGroupName

az role assignment delete --assignee appID \
                          --role Contributor \
                          --scope /subscriptions/mySubscriptionID/resourceGroups/myResourceGroupName

新增角色「不會」限制之前指派的權限。 限制服務主體的許可權時,如果先前已 指派參與者角色 ,則應移除參與者角色。

列出指派的角色可以驗證變更:

az role assignment list --assignee appID

4.使用服務主體登入

藉由登入來測試新服務主體的認證和權限。 若要使用服務主體登入,您需要 appIdtenant 和認證。

透過服務主體來使用密碼登入:

az login --service-principal --username appID --password PASSWORD --tenant tenantID

若要使用憑證登入,該憑證必須是可在本機使用的 PEM 或 DER 檔案,並且採用 ASCII 格式。 使用 PEM 檔案時,必須將 私密金鑰憑證 一起附加至檔案。

az login --service-principal --username appID --tenant tenantID --password /path/to/cert

若要深入了解如何使用服務主體登入,請參閱使用 Azure CLI 登入

5.使用服務主體建立資源

下一節提供的範例示範如何使用下列命令,透過服務主體建立 Azure 儲存體的資源:

若要使用服務主體來登入,當您建立服務主體時,您需要傳回 appIDtenantIDpassword 作為回應。

  1. 以服務主體的形式登入。

    az login --service-principal --username appID --password PASSWORD --tenant tenantID
    
  2. 建立資源群組,以保存用於相同快速入門、教學課程或開發專案的所有資源。

    az group create --location westus --name myResourceGroupName
    
  3. 建立儲存體帳戶。

    針對 Azure 儲存體,<KIND> 參數的有效值為:

    • BlobStorage
    • BlockBlobStorage
    • FileStorage
    • 儲存體
    • StorageV2
    az storage account create --name myStorageAccountName --resource-group myResourceGroupName --kind <KIND> --sku F0 --location westus --yes
    
  4. 取得您在程式碼中使用的資源金鑰,以向 Azure 儲存體帳戶進行驗證。

    az storage account keys list --name myStorageAccountName --resource-group myResourceGroupName
    

6.重設認證

如果您遺失服務主體的認證,請使用 az ad sp credential reset。 reset 命令會採用與 相同的參數 az ad sp create-for-rbac

az ad sp credential reset --name myServicePrincipal_appID_or_name

7.疑難排解

權限不足

如果您的帳戶沒有建立服務主體的權限,az ad sp create-for-rbac 會傳回「權限不足,無法完成作業」的錯誤訊息。 請連絡您的 Azure Active Directory 管理員,以建立服務主體。

不正確租使用者

如果您指定了不正確訂用帳戶識別碼,您會看到錯誤訊息「要求沒有訂用帳戶或有效的租使用者層級資源提供者」。 如果使用變數,請使用 Bash echo 命令來查看傳遞至參考命令的值。 使用 az account set 來變更您的訂用帳戶,或瞭解如何 使用 Azure CLI 管理 Azure 訂用帳戶

找不到資源群組

如果您指定了不正確資源組名,您會看到錯誤訊息「找不到資源組名」。 如果使用變數,請使用 Bash echo 命令來查看傳遞至訂用帳戶和參考命令的值。 使用 az group list 查看目前訂用帳戶的資源群組,或 瞭解如何使用 Azure CLI 管理 Azure 資源群組

執行動作的授權

如果您的帳戶沒有足夠權限可指派角色,您會看到錯誤訊息,這表示您的帳戶「沒有執行 'Microsoft.Authorization/roleAssignments/write' 動作的權限」。請連絡您的 Azure Active Directory 管理員,以管理角色。

另請參閱