使用 Azure CLI 來建立 Azure 服務主體
使用 Azure 服務的自動化工具應一律具有權限限制。 Azure 提供的服務主體,可替代以具有完整權限的使用者身分登入應用程式。
什麼是 Azure 服務主體?
Azure 服務主體是一種身分識別,建立目的是為了搭配應用程式、託管服務及自動化工具來存取 Azure 資源。 此存取會受限於指派給服務主體的角色,以便您控制可存取的資源,以及在哪個層級上存取。 基於安全理由,我們建議您一律搭配自動化工具使用服務主體,而不是讓服務主體透過使用者身分識別來登入。
本文說明使用 Azure CLI 建立、取得 Azure 服務主體的相關資訊,以及重設 Azure 服務主體的步驟。
1.建立服務主體
使用 az ad sp create-for-rbac 命令建立 Azure 服務主體。
appId
和 tenant
索引鍵會出現在 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 list
或 az 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.使用服務主體登入
藉由登入來測試新服務主體的認證和權限。 若要使用服務主體登入,您需要 appId
、tenant
和認證。
透過服務主體來使用密碼登入:
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 儲存體的資源:
若要使用服務主體來登入,當您建立服務主體時,您需要傳回 appID
、tenantID
和 password
作為回應。
以服務主體的形式登入。
az login --service-principal --username appID --password PASSWORD --tenant tenantID
建立資源群組,以保存用於相同快速入門、教學課程或開發專案的所有資源。
az group create --location westus --name myResourceGroupName
建立儲存體帳戶。
針對 Azure 儲存體,
<KIND>
參數的有效值為:- BlobStorage
- BlockBlobStorage
- FileStorage
- 儲存體
- StorageV2
az storage account create --name myStorageAccountName --resource-group myResourceGroupName --kind <KIND> --sku F0 --location westus --yes
取得您在程式碼中使用的資源金鑰,以向 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 管理員,以管理角色。