为应用程序角色分配托管标识访问权限

Azure 资源的托管标识在 Microsoft Entra ID 中为 Azure 服务提供了一个标识。 它们无需在代码中使用凭据即可工作。 Azure 服务使用此标识向支持 Microsoft Entra 身份验证的服务证明身份。 应用程序角色提供了一种基于角色的访问控制形式,并允许服务实现授权规则。

注意

应用程序收到的令牌由底层基础结构缓存。 这意味着,对托管标识角色的任何更改都可能需要大量时间来处理。 有关详细信息,请参阅使用托管标识进行授权的限制

本文介绍如何使用 Microsoft Graph PowerShell SDK 向另一应用程序公开的应用程序角色分配托管标识。

先决条件

使用 PowerShell 将托管标识访问权限分配给另一应用程序的应用角色

若要在本地运行脚本,请安装最新版本的 Microsoft Graph PowerShell SDK

  1. 在 Azure 资源上启用托管标识,如 Azure VM

  2. 查找托管标识的服务主体的对象 ID。

    对于系统分配的托管标识,可在 Azure 门户中资源的“标识”页上找到对象 ID 。 还可以使用以下 PowerShell 脚本来查找对象 ID。 你将需要步骤 1 中所创建资源的资源 ID,可在 Azure 门户中资源的“属性”页上找到该 ID。

    $resourceIdWithManagedIdentity = '/subscriptions/{my subscription ID}/resourceGroups/{my resource group name}/providers/Microsoft.Compute/virtualMachines/{my virtual machine name}'
    (Get-AzResource -ResourceId $resourceIdWithManagedIdentity).Identity.PrincipalId
    

    对于用户分配的托管标识,可在 Azure 门户中资源的“概述”页上找到托管标识的对象 ID 。 还可以使用以下 PowerShell 脚本来查找对象 ID。 你将需要用户分配的托管标识的资源 ID。

    $userManagedIdentityResourceId = '/subscriptions/{my subscription ID}/resourceGroups/{my resource group name}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{my managed identity name}'
    (Get-AzResource -ResourceId $userManagedIdentityResourceId).Properties.PrincipalId
    
  3. 创建新的应用程序注册,以表示托管标识要向其发送请求的服务。

    • 如果公开向托管标识授予的应用角色的 API 或服务在 Microsoft Entra 租户中已有服务主体,请跳过此步骤。 例如,在想要授予托管标识对 Microsoft Graph API 的访问权限的情况下。
  4. 查找服务应用程序的服务主体的对象 ID。 可以使用 Azure 门户来查找此 ID。

    • 例如,转到 Microsoft Entra ID 并打开“企业应用程序”页面。 然后找到该应用程序并查看“对象 ID”
    • 还可以使用以下 PowerShell 脚本,按照服务主体的对象 ID 的显示名称找到此 ID:
    $serverServicePrincipalObjectId = (Get-MgServicePrincipal -Filter "DisplayName eq '$applicationName'").Id
    

    注意

    应用程序的显示名称不是唯一的,因此,应验证是否获取了正确的应用程序服务主体。

  5. 为上一步骤中创建的应用程序添加应用角色。 然后可以使用 Azure 门户或使用 Microsoft Graph 来创建角色。

  6. 将应用角色分配给托管标识。 你将需要以下信息来分配应用角色:

    • managedIdentityObjectId:在前面步骤中找到的托管标识服务主体的对象 ID。
    • serverServicePrincipalObjectId:在步骤 4 中找到的服务器应用程序服务主体的对象 ID。
    • appRoleId:在步骤 5 中生成的服务器应用公开的应用角色 ID,此示例中的应用角色 ID 为 00000000-0000-0000-0000-000000000000
    • 执行以下 PowerShell 命令以添加角色分配:
    New-MgServicePrincipalAppRoleAssignment `
        -ServicePrincipalId $serverServicePrincipalObjectId `
        -PrincipalId $managedIdentityObjectId `
        -ResourceId $serverServicePrincipalObjectId `
        -AppRoleId $appRoleId
    

完整的示例脚本

此示例脚本演示如何将 Azure Web 应用的托管标识分配给应用角色。

# Install the module.
# Install-Module Microsoft.Graph -Scope CurrentUser

# Your tenant ID (in the Azure portal, under Azure Active Directory > Overview).
$tenantID = '<tenant-id>'

# The name of your web app, which has a managed identity that should be assigned to the server app's app role.
$webAppName = '<web-app-name>'
$resourceGroupName = '<resource-group-name-containing-web-app>'

# The name of the server app that exposes the app role.
$serverApplicationName = '<server-application-name>' # For example, MyApi

# The name of the app role that the managed identity should be assigned to.
$appRoleName = '<app-role-name>' # For example, MyApi.Read.All

# Look up the web app's managed identity's object ID.
$managedIdentityObjectId = (Get-AzWebApp -ResourceGroupName $resourceGroupName -Name $webAppName).identity.principalid

Connect-MgGraph -Environment China -ClientId 'YOUR_CLIENT_ID' -TenantId $tenantId -Scopes 'Application.Read.All','Application.ReadWrite.All','AppRoleAssignment.ReadWrite.All','Directory.AccessAsUser.All','Directory.Read.All','Directory.ReadWrite.All'

# Look up the details about the server app's service principal and app role.
$serverServicePrincipal = (Get-MgServicePrincipal -Filter "DisplayName eq '$serverApplicationName'")
$serverServicePrincipalObjectId = $serverServicePrincipal.Id
$appRoleId = ($serverServicePrincipal.AppRoles | Where-Object {$_.Value -eq $appRoleName }).Id

# Assign the managed identity access to the app role.
New-MgServicePrincipalAppRoleAssignment `
    -ServicePrincipalId $serverServicePrincipalObjectId `
    -PrincipalId $managedIdentityObjectId `
    -ResourceId $serverServicePrincipalObjectId `
    -AppRoleId $appRoleId

使用 CLI 将托管标识访问权限分配给另一应用程序的应用角色

  • 如需在本地运行 CLI 参考命令,请安装 Azure CLI。 如果在 Windows 或 macOS 上运行,请考虑在 Docker 容器中运行 Azure CLI。 有关详细信息,请参阅如何在 Docker 容器中运行 Azure CLI

    • 如果使用的是本地安装,请使用 az login 命令登录到 Azure CLI。 若要完成身份验证过程,请遵循终端中显示的步骤。 有关其他登录选项,请参阅使用 Azure CLI 登录

    • 出现提示时,请在首次使用时安装 Azure CLI 扩展。 有关扩展详细信息,请参阅使用 Azure CLI 的扩展

    • 运行 az version 以查找安装的版本和依赖库。 若要升级到最新版本,请运行 az upgrade

  1. 在 Azure 资源上启用托管标识,如 Azure 虚拟机

  2. 查找托管标识的服务主体的对象 ID。

    • 对于系统分配的托管标识,可在 Azure 门户中资源的“标识”页上找到对象 ID 。
    • 还可使用以下脚本查找对象 ID。 需要前面步骤中所创建资源的资源 ID,可在 Azure 门户中资源的“属性”页上找到该 ID
    resourceIdWithManagedIdentity="/subscriptions/{my subscription ID}/resourceGroups/{my resource group name}/providers/Microsoft.Compute/virtualMachines/{my virtual machine name}"
    
    oidForMI=$(az resource show --ids $resourceIdWithManagedIdentity --query "identity.principalId" -o tsv | tr -d '[:space:]')
    echo "object id for managed identity is: $oidForMI"
    
    • 对于用户分配的托管标识,可在 Azure 门户中资源的“概述”页上找到托管标识的对象 ID 。 还可使用以下脚本查找对象 ID。 你将需要用户分配的托管标识的资源 ID。
    userManagedIdentityResourceId="/subscriptions/{my subscription ID}/resourceGroups/{my resource group name}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{my managed identity name}"
    
    oidForMI=$(az resource show --id $userManagedIdentityResourceId --query "properties.principalId" -o tsv | tr -d '[:space:]')
    echo "object id for managed identity is: $oidForMI"
    
  3. 创建新的应用程序注册,以表示托管标识要向其发送请求的服务。

    • 如果公开向托管标识授予的应用角色的 API 或服务在 Microsoft Entra 租户中已有服务主体,请跳过此步骤。
  4. 查找服务应用程序的服务主体的对象 ID。 可以使用 Azure 门户来查找此 ID。

    • 转到 Microsoft Entra ID 并打开“企业应用程序”页,然后找到应用程序并查找“对象 ID”。
    • 还可以使用以下脚本,按照服务主体的对象 ID 的显示名称找到此 ID:
    appName="{name for your application}"
    serverSPOID=$(az ad sp list --filter "displayName eq '$appName'" --query '[0].id' -o tsv | tr -d '[:space:]')
    echo "object id for server service principal is: $serverSPOID"
    

    注意

    应用程序的显示名称不是唯一的,因此,应验证是否获取了正确的应用程序服务主体。

    或者,可以通过应用程序注册的唯一应用程序 ID 查找对象 ID:

    appID="{application id for your application}"
    serverSPOID=$(az ad sp list --filter "appId eq '$appID'" --query '[0].id' -o tsv | tr -d '[:space:]')
    echo "object id for server service principal is: $serverSPOID"
    
  5. 为上一步骤中创建的应用程序添加应用角色。 可以使用 Azure 门户或使用 Microsoft Graph 来创建角色。 例如,可以添加如下应用角色:

    {
        "allowedMemberTypes": [
            "Application"
        ],
        "displayName": "Read data from MyApi",
        "id": "0566419e-bb95-4d9d-a4f8-ed9a0f147fa6",
        "isEnabled": true,
        "description": "Allow the application to read data as itself.",
        "value": "MyApi.Read.All"
    }
    
  6. 将应用角色分配给托管标识。 你将需要以下信息来分配应用角色:

    • managedIdentityObjectId:在步骤 2 中找到的托管标识服务主体的对象 ID。
    • serverServicePrincipalObjectId:在步骤 4 中找到的服务器应用程序服务主体的对象 ID。
    • appRoleId:在步骤 5 中生成的服务器应用公开的应用角色 ID,此示例中的应用角色 ID 为 00000000-0000-0000-0000-000000000000
  7. 执行以下脚本以添加角色分配。 不直接在 Azure CLI 上公开此功能,而是在此处使用 REST 命令:

    roleguid="00000000-0000-0000-0000-000000000000"
    az rest -m POST -u https://microsoftgraph.chinacloudapi.cn/v1.0/servicePrincipals/$oidForMI/appRoleAssignments -b "{\"principalId\": \"$oidForMI\", \"resourceId\": \"$serverSPOID\",\"appRoleId\": \"$roleguid\"}"
    

后续步骤