你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

使用 Azure CLI 创建 Azure 服务主体

使用 Azure 服务的自动化工具应始终具有受限权限。 Azure 提供了服务主体,而不是让应用程序以具有完全特权的用户身份登录。

什么是 Azure 服务主体?

Azure 服务主体是为与应用程序、托管服务和自动化工具配合使用以访问 Azure 资源而创建的标识。 此访问权限受分配给服务主体的角色限制,可用于控制哪些资源可以访问以及在哪个级别进行访问。 出于安全原因,始终建议将服务主体与自动化工具配合使用,而不是允许它们使用用户标识进行登录。

本文介绍了用于使用 Azure CLI 创建 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 参数。 此参数需要你持有现有的证书。 请确保任何使用此服务主体的工具都有权访问该证书的私钥。 证书应采用 PEM、CER 或 DER 等 ASCII 格式。 请将证书作为字符串传递,或使用 @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 Key Vault 中的证书。 在这种情况下,--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 Key Vault 中。 使用 --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 密钥。 此密钥的值指示所生成的证书的存储位置。 请确保将证书复制到安全位置,否则将无法使用此服务主体登录。

如果无法访问证书的私钥,请重置服务主体凭据

检索来自 Key Vault 的证书

对于 Key Vault 中存储的证书,请使用 az keyvault secret show 检索包含私钥的证书,并将其转换为 PEM 文件。 在 Key Vault 中,证书机密的名称与证书名称相同。

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。 该重置命令带有与 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 管理员联系以创建服务主体。

租户无效

如果指定了无效的订阅 ID,你会看到错误消息“请求没有订阅或有效的租户级别资源提供程序。”如果使用变量,请使用 Bash echo 命令查看要传递给引用命令的值。 使用 az account set 更改订阅,或了解如何通过 Azure CLI 管理 Azure 订阅

找不到资源组

如果指定的资源组名称无效,你会看到错误消息“找不到资源组“名称”。”如果使用变量,请使用 Bash echo 命令查看要同时传递给订阅和引用命令的值。 使用 az group list 查看当前订阅的资源组,或了解如何使用 Azure CLI 管理 Azure 资源组

执行操作的授权

如果帐户无权分配角色,则将显示错误消息“你的帐户无权执行操作 'Microsoft.Authorization/roleAssignments/write'”。请与 Azure Active Directory 管理员联系以管理角色。

另请参阅