配置用户分配的托管标识以信任外部标识提供者

本文介绍如何在 Microsoft Entra ID 中管理用户分配的托管标识的联合标识凭据。 联合标识凭据在用户分配的托管标识与外部标识提供者 (IdP) 之间创建信任关系。 不支持在系统分配的托管标识上配置联合标识凭据。

将用户分配的托管标识配置为信任外部 IdP 后,配置外部软件工作负载以将来自外部 IdP 的令牌交换为来自 Microsoft 标识平台的访问令牌。 外部工作负载使用访问令牌来访问 Microsoft Entra 受保护的资源,而无需管理机密(在支持的场景中)。 若要详细了解令牌交换工作流,请阅读工作负载标识联合验证

本文介绍如何在用户分配的托管标识中创建、列出和删除联合标识凭据。

重要注意事项和限制

最多可以向应用程序或用户分配的托管标识添加 20 个联合标识凭据。

配置联合标识凭据时,需要提供几条重要信息:

  • issuer 和 subject 是建立信任关系所需的关键信息 。 issuersubject 的组合在应用中必须唯一。 当外部软件工作负载请求 Microsoft 标识平台来交换访问令牌的外部令牌时,将针对外部令牌中提供的 issuersubject 声明来检查联合标识凭据的 issuer 和 subject 值 。 如果该验证检查通过,Microsoft 标识平台会向外部软件工作负载发出访问令牌。

  • issuer 是外部身份提供商的 URL,必须与要交换的外部令牌的 issuer 声明相匹配。 必需。 如果 issuer 声明具有值中的前导或尾随空格,则会阻止令牌交换。 此字段的字符限制为 600 个字符。

  • subject 是外部标识提供者的标识符,必须与要交换的外部令牌的 sub (subject) 声明相匹配。 subject 没有固定格式,因为每个 IdP 都使用自己的格式,格式有时是 GUID,有时是冒号分隔的标识符,有时是任意字符串。 此字段的字符限制为 600 个字符。

    重要

    “subject”设置值必须与 GitHub 工作流配置中的配置完全匹配。 否则,Microsoft 标识平台将查看传入的外部令牌,并拒绝交换访问令牌。 你不会收到错误消息,交换失败且没有错误。

    重要

    如果在 subject 设置中意外添加了不正确的外部工作负载信息,则已成功创建联合标识凭据,且未出现错误。 在令牌交换失败之前,此错误不会变得明显。

  • audiences 列出了可出现在外部令牌中的受众。 必需。 必须添加一个受众值,该值限制为 600 个字符。 建议的值为“api://AzureADTokenExchange”。 它表示 Microsoft 标识平台必须接受传入令牌中的 aud 声明。

  • name 是联合标识凭据的唯一标识符。 必需。 此字段的字符限制为 3-120 个字符,并且必须对 URL 友好。 支持字母数字、短划线或下划线字符,第一个字符必须是字母数字字符。  它在创建后就不可变。

  • description 是用户提供的联合标识凭据的说明。 可选。 Microsoft Entra ID 不会验证或检查说明。 此字段的上限为 600 个字符。

任何联合标识凭据属性值都不支持通配符。

若要详细了解受支持的区域、传播联合凭据更新的时间、支持的颁发者等,请阅读联合标识凭据的重要注意事项和限制

先决条件

在用户分配的托管标识上配置联合标识凭据

Microsoft Entra 管理中心中,导航到你创建的用户分配的托管标识。 在左侧导航栏中的“设置”下,选择“联合凭据”,然后选择“添加凭据”。

在“联合凭据场景”下拉列表框中,选择你的场景。

部署 Azure 资源的 GitHub Actions

要为 GitHub 操作添加联合身份,请执行以下步骤:

  1. 对于“实体类型”,请选择“环境”、“分支”、“拉取请求”或“标记”,并指定值 。 值必须与 GitHub 工作流中的配置完全匹配。 有关详细信息,请阅读示例

  2. 为联合凭据添加“名称”。

  3. “颁发者”、“受众”和“主题标识符”字段会根据你输入的值自动填充 。

  4. 选择“添加”以配置联合凭据。

将你的 Microsoft Entra 托管标识中的以下值用于你的 GitHub 工作流:

  • AZURE_CLIENT_ID,托管标识客户端 ID

  • AZURE_SUBSCRIPTION_ID,订阅 ID。

    下面的屏幕截图演示了如何复制托管标识 ID 和订阅 ID。

    Screenshot that demonstrates how to copy the managed identity ID and subscription ID from Azure portal.

  • AZURE_TENANT_ID 目录(租户)ID。 了解如何查找 Microsoft Entra 租户 ID

实体类型示例

分支示例

对于主分支上的推送或拉取请求事件触发的工作流,请执行以下操作:

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

将“实体类型”指定为“分支”,将“GitHub 分支名称”指定为“main”。

环境示例

对于绑定到名为“production”的环境的“作业”,请执行以下操作:

on:
  push:
    branches:
      - main

jobs:
  deployment:
    runs-on: ubuntu-latest
    environment: production
    steps:
      - name: deploy
        # ...deployment-specific steps

将“实体类型”指定为“环境”,将“GitHub 环境名称”指定为“production”。

标记示例

例如,对于目标为标记“v2”的推送触发的工作流,请执行以下操作:

on:
  push:
    # Sequence of patterns matched against refs/heads
    branches:
      - main
      - 'mona/octocat'
      - 'releases/**'
    # Sequence of patterns matched against refs/tags
    tags:
      - v2
      - v1.*

将“实体类型”指定为“标记”,将“GitHub 标记名称”指定为“v2”。

拉取请求示例

对于拉取请求事件触发的工作流,请将“实体类型”指定为“拉取请求”

访问 Azure 资源的 Kubernetes

填写“群集证书颁发者 URL”、“命名空间”、“服务帐户名称”和“名称”字段:

  • “群集证书颁发者 URL”是托管群集的 OIDC 证书颁发者 URL 或自托管群集的 OIDC 证书颁发者 URL
  • “服务帐户名称”是 Kubernetes 服务帐户的名称,它为 Pod 中运行的进程提供标识。
  • “命名空间”是服务帐户命名空间。
  • “Name”是联合凭据的名称,以后将无法更改。

选择“添加”以配置联合凭据。

其他

从下拉菜单中选择“其他证书颁发者”场景。

指定以下字段:

  • Name 是联合凭据的名称,以后将无法更改。
  • 主题标识符:必须与外部标识提供者颁发的令牌中的 sub 声明匹配。
  • 证书颁发者:必须与外部标识提供者颁发的令牌中的 iss 声明匹配。 符合 OIDC 发现规范的 URL。Microsoft Entra ID 使用此颁发者 URL 提取验证令牌所需的密钥。

选择“添加”以配置联合凭据。

在用户分配的托管标识上列出联合标识凭据

Microsoft Entra 管理中心中,导航到你创建的用户分配的托管标识。 在左侧导航栏中的“设置”下,选择“联合凭据”。

在该用户分配的托管标识上配置的联合标识凭据已列出。

从用户分配的托管标识中删除联合标识凭据

Microsoft Entra 管理中心中,导航到你创建的用户分配的托管标识。 在左侧导航栏中的“设置”下,选择“联合凭据”。

在该用户分配的托管标识上配置的联合标识凭据已列出。

若要删除特定联合标识凭据,请选择凭据的“删除”图标。

先决条件

在用户分配的托管标识上配置联合标识凭据

运行 az identity federated-credential create 命令,在用户分配的托管标识(由相应名称指定)上创建新的联合标识凭据。 指定 name、issuer、subject 和其他参数。

az login

# set variables
location="chinanorth"
subscription="{subscription-id}"
rg="fic-test-rg"

# user assigned identity name
uaId="fic-test-ua"

# federated identity credential name
ficId="fic-test-fic-name"

# create prerequisites if required.
# otherwise make sure that existing resources names are set in variables above
az account set --subscription $subscription
az group create --location $location --name $rg
az identity create --name $uaId --resource-group $rg --location $location --subscription $subscription

# Create/update a federated identity credential
az identity federated-credential create --name $ficId --identity-name $uaId --resource-group $rg --issuer 'https://aks.azure.com/issuerGUID' --subject 'system:serviceaccount:ns:svcaccount' --audiences 'api://AzureADTokenExchange'

在用户分配的托管标识上列出联合标识凭据

运行 az identity federated-credential list 命令,读取在用户分配的托管标识上配置的所有联合标识凭据:

az login

# Set variables
rg="fic-test-rg"

# User assigned identity name
uaId="fic-test-ua"

# Read all federated identity credentials assigned to the user-assigned managed identity
az identity federated-credential list --identity-name $uaId --resource-group $rg

在用户分配的托管标识上获取联合标识凭据

运行 az identity federated-credential show 命令,显示联合标识凭据(按 ID):

az login

# Set variables
rg="fic-test-rg"

# User assigned identity name
uaId="fic-test-ua"

# Federated identity credential name
ficId="fic-test-fic-name"

# Show the federated identity credential
az identity federated-credential show --name $ficId --identity-name $uaId --resource-group $rg

从用户分配的托管标识中删除联合标识凭据

运行 az identity federated-credential delete 命令,删除现有用户分配的标识下的联合标识凭据。

az login

# Set variables
# in Linux shell remove $ from set variable statement
$rg="fic-test-rg"

# User assigned identity name
$uaId="fic-test-ua"

# Federated identity credential name
$ficId="fic-test-fic-name"

az identity federated-credential delete --name $ficId --identity-name $uaId --resource-group $rg

先决条件

在本地配置 Azure PowerShell

若要在本文情景中本地使用 Azure PowerShell:

  1. 安装最新版本的 Azure PowerShell(如果尚未安装)。

  2. 登录 Azure。

    Connect-AzAccount -Environment AzureChinaCloud
    
  3. 安装最新版本的 PowerShellGet

    Install-Module -Name PowerShellGet -AllowPrerelease
    

    在下一步运行此命令后,可能需要 Exit 退出当前 PowerShell 会话。

  4. 安装 Az.ManagedServiceIdentity 模块,以执行本文中用户分配的托管标识操作。

    Install-Module -Name Az.ManagedServiceIdentity
    

在用户分配的托管标识上配置联合标识凭据

运行 New-AzFederatedIdentityCredentials 命令,在用户分配的托管标识(由相应名称指定)上创建新的联合标识凭据。 指定 name、issuer、subject 和其他参数。

New-AzFederatedIdentityCredentials -ResourceGroupName azure-rg-test -IdentityName uai-pwsh01 `
    -Name fic-pwsh01 -Issuer "https://kubernetes-oauth.azure.com" -Subject "system:serviceaccount:ns:svcaccount"

在用户分配的托管标识上列出联合标识凭据

运行 Get-AzFederatedIdentityCredentials 命令,读取在用户分配的托管标识上配置的所有联合标识凭据:

Get-AzFederatedIdentityCredentials -ResourceGroupName azure-rg-test -IdentityName uai-pwsh01

在用户分配的托管标识上获取联合标识凭据

运行 Get-AzFederatedIdentityCredentials 命令,显示联合标识凭据(按名称):

Get-AzFederatedIdentityCredentials -ResourceGroupName azure-rg-test -IdentityName uai-pwsh01 -Name fic-pwsh01

从用户分配的托管标识中删除联合标识凭据

运行 Remove-AzFederatedIdentityCredentials 命令,删除现有用户分配标识下的联合标识凭据。

Remove-AzFederatedIdentityCredentials -ResourceGroupName azure-rg-test -IdentityName uai-pwsh01 -Name fic-pwsh01

先决条件

模板创建和编辑

资源管理器模板有助于部署由 Azure 资源组定义的新资源或已修改资源。 有多种可用于执行模板编辑和部署的方法(包括本地方法和基于门户的方法)。 方法:

在用户分配的托管标识上配置联合标识凭据

联合标识凭据和父级用户分配的标识可通过以下模板创建或更新。 可以从 Azure 门户部署 ARM 模板

所有模板参数都是必需的。

联合标识凭据名称长度限制为 3-120 个字符。 名称必须为字母数字、短划线、下划线。 第一个符号仅为字母数字。

必须向联合标识凭据添加正好 1 名受众。 将在令牌交换期间对该受众进行验证。 使用“api://AzureADTokenExchange”作为默认值。

模板不提供列表、获取和删除操作。 有关这些操作,请参阅 Azure CLI。 默认情况下,所有子级联合标识凭据都并行创建,这会触发并发检测逻辑,并导致部署失败并出现 409 冲突的 HTTP 状态代码。 若要按顺序创建,请使用 dependsOn 属性指定依赖项链。

确保任何类型的自动化都按顺序在同一父标识下创建联合标识凭据。 联合标识凭据可在不同托管标识下并行创建,且没有任何限制。

{

    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "variables": {},
    "parameters": {
        "location": {
            "type": "string",
            "defaultValue": "chinanorth",
            "metadata": {
                "description": "Location for identities resources. FIC should be enabled in this region."
            }
        },
        "userAssignedIdentityName": {
            "type": "string",
            "defaultValue": "FIC_UA",
            "metadata": {
                "description": "Name of the User Assigned identity (parent identity)"
            }
        },
        "federatedIdentityCredential": {
            "type": "string",
            "defaultValue": "testCredential",
            "metadata": {
                "description": "Name of the Federated Identity Credential"
            }
        },
        "federatedIdentityCredentialIssuer": {
            "type": "string",
            "defaultValue": "https://aks.azure.com/issuerGUID",
            "metadata": {
                "description": "Federated Identity Credential token issuer"
            }
        },
        "federatedIdentityCredentialSubject": {
            "type": "string",
            "defaultValue": "system:serviceaccount:ns:svcaccount",
            "metadata": {
                "description": "Federated Identity Credential token subject"
            }
        },
        "federatedIdentityCredentialAudience": {
            "type": "string",
            "defaultValue": " api://AzureADTokenExchange",
            "metadata": {
                "description": "Federated Identity Credential audience. Single value is only supported."
            }
        }
    },
    "resources": [
        {
            "type": "Microsoft.ManagedIdentity/userAssignedIdentities",
            "apiVersion": "2018-11-30",
            "name": "[parameters('userAssignedIdentityName')]",
            "location": "[parameters('location')]",
            "tags": {
                "firstTag": "ficTest"
            },
            "resources": [
                {
                    "type": "Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials",
                    "apiVersion": "2022-01-31-PREVIEW",
                    "name": "[concat(parameters('userAssignedIdentityName'), '/', parameters('federatedIdentityCredential'))]",
                    "dependsOn": [
                      "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('userAssignedIdentityName'))]"
                    ],
                    "properties": {
                        "issuer": "[parameters('federatedIdentityCredentialIssuer')]",
                        "subject": "[parameters('federatedIdentityCredentialSubject')]",
                        "audiences": [
                            "[parameters('federatedIdentityCredentialAudience')]"
                        ]
                    }
                }
            ]
        }
    ]
}

先决条件

获取持有者访问令牌

  1. 如果在本地运行,请通过 Azure CLI 登录到 Azure。

    az login
    
  2. 使用 az account get-access-token 获取访问令牌。

    az account get-access-token
    

在用户分配的托管标识上配置联合标识凭据

在用户分配的指定托管标识上创建或更新联合标识凭据

curl 'https://management.chinacloudapi.cn/subscriptions/<SUBSCRIPTION ID>/resourceGroups/<RESOURCE GROUP>/provider
s/Microsoft.ManagedIdentity/userAssignedIdentities/<USER ASSIGNED IDENTITY NAME>/federatedIdenti
tyCredentials/<FEDERATED IDENTITY CREDENTIAL NAME>?api-version=2022-01-31-preview' -X PUT -d '{"properties": "{ "properties": { "issuer": "<ISSUER>", "subject": "<SUBJECT>", "audiences": [ "api://AzureADTokenExchange" ] }}"}' -H "Content-Type: application/json" -H "Authorization: Bearer <ACCESS TOKEN>"
PUT https://management.chinacloudapi.cn/subscriptions/<SUBSCRIPTION ID>/resourceGroups/<RESOURCE GROUP>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<USER ASSIGNED IDENTITY NAME>/federatedIdentityCredentials/<FEDERATED IDENTITY CREDENTIAL NAME>?api-version=2022-01-31-preview

{
 "properties": {
 "issuer": "https://oidc.prod-aks.azure.com/IssuerGUID",
 "subject": "system:serviceaccount:ns:svcaccount",
 "audiences": [
 "api://AzureADTokenExchange"
 ]
 }
}

请求标头

请求标头 说明
Content-Type 必需。 设置为 application/json
授权 必需。 设置为有效的 Bearer 访问令牌。

请求正文

名称 说明
properties.audiences 必需。 可在颁发的令牌中显示的受众列表。
properties.issuer 必需。 要信任的颁发者的 URL。
properties.subject 必需。 外部文件的标识符。

在用户分配的托管标识上列出联合标识凭据

在用户分配的指定托管标识上列出所有联合标识凭据

curl 'https://management.chinacloudapi.cn/subscriptions/<SUBSCRIPTION ID>/resourceGroups/<RESOURCE GROUP>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<USER ASSIGNED IDENTITY NAME>/<RESOURCE NAME>/federatedIdentityCredentials?api-version=2022-01-31-preview' -H "Content-Type: application/json" -X GET -H "Authorization: Bearer <ACCESS TOKEN>"
GET
https://management.chinacloudapi.cn/subscriptions/<SUBSCRIPTION ID>/resourceGroups/<RESOURCE GROUP>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<USER ASSIGNED IDENTITY NAME>/<RESOURCE NAME>/federatedIdentityCredentials?api-version=2022-01-31-preview

请求标头

请求标头 说明
Content-Type 必需。 设置为 application/json
授权 必需。 设置为有效的 Bearer 访问令牌。

在用户分配的托管标识上获取联合标识凭据

在用户分配的指定托管标识上获取联合标识凭据

curl 'https://management.chinacloudapi.cn/subscriptions/<SUBSCRIPTION ID>/resourceGroups/<RESOURCE GROUP>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<USER ASSIGNED IDENTITY NAME>/<RESOURCE NAME>/federatedIdentityCredentials/<FEDERATED IDENTITY CREDENTIAL RESOURCENAME>?api-version=2022-01-31-preview' -X GET -H "Content-Type: application/json" -H "Authorization: Bearer <ACCESS TOKEN>"
GET
https://management.chinacloudapi.cn/subscriptions/<SUBSCRIPTION ID>/resourceGroups/<RESOURCE GROUP>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<USER ASSIGNED IDENTITY NAME>/<RESOURCE NAME>/federatedIdentityCredentials/<FEDERATED IDENTITY CREDENTIAL RESOURCENAME>?api-version=2022-01-31-preview

请求标头

请求标头 说明
Content-Type 必需。 设置为 application/json
授权 必需。 设置为有效的 Bearer 访问令牌。

从用户分配的托管标识中删除联合标识凭据

在用户分配的指定托管标识上删除联合标识凭据

curl 'https://management.chinacloudapi.cn/subscriptions/<SUBSCRIPTION ID>/resourceGroups/<RESOURCE GROUP>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<USER ASSIGNED IDENTITY NAME>/<RESOURCE NAME>/federatedIdentityCredentials/<FEDERATED IDENTITY CREDENTIAL RESOURCENAME>?api-version=2022-01-31-preview' -X DELETE -H "Content-Type: application/json" -H "Authorization: Bearer <ACCESS TOKEN>"
DELETE
https://management.chinacloudapi.cn/subscriptions/<SUBSCRIPTION ID>/resourceGroups/<RESOURCE GROUP>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<USER ASSIGNED IDENTITY NAME>/<RESOURCE NAME>/federatedIdentityCredentials/<FEDERATED IDENTITY CREDENTIAL RESOURCENAME>?api-version=2022-01-31-preview

请求标头

请求标头 说明
Content-Type 必需。 设置为 application/json
授权 必需。 设置为有效的 Bearer 访问令牌。

后续步骤

  • 有关由外部标识提供者创建的 JWT 所需格式的信息,请阅读断言格式