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

使用 JSON Web 令牌通过命名空间进行身份验证

本文介绍如何使用 JSON Web 令牌通过 Azure 事件网格命名空间进行身份验证。

Azure 事件网格的 MQTT 代理支持自定义 JWT 身份验证,使客户端可以使用任何标识提供者(Microsoft Entra ID 之外)颁发的 JSON Web 令牌通过事件网格命名空间进行连接和身份验证。

先决条件

若要对命名空间使用自定义 JWT 身份验证,需要满足以下先决条件:

  • 可以颁发 Json Web 令牌的标识提供者。
  • 包含用于验证客户端令牌的公钥的 CA 证书。
  • 用于托管包含公钥的 CA 证书的 Azure 密钥保管库帐户。

简要步骤

要对命名空间使用自定义 JWT 身份验证,请执行以下步骤:

  1. 创建命名空间并配置其子资源。
  2. 在事件网格命名空间上启用托管标识。
  3. 创建托管包含公钥的 CA 证书的 Azure 密钥保管库帐户。
  4. 在 Azure 密钥保管库中为命名空间的托管标识添加角色分配。
  5. 在事件网格命名空间上配置自定义身份验证设置
  6. 客户端可以使用标识提供者提供的令牌连接到事件网格命名空间。

创建命名空间并配置其子资源

按照快速入门:使用 Azure 门户在事件网格命名空间上发布和订阅 MQTT 消息创建命名空间并配置其子资源。 跳过证书和客户端创建步骤,因为客户端标识来自提供的令牌。 客户端属性基于客户端令牌中的自定义声明。 客户端属性用于客户端组查询、主题模板变量和路由扩充配置。

在事件网格命名空间上启用托管标识

命名空间使用托管标识访问 Azure 密钥保管库实例,以获取自定义域的服务器证书。 使用以下命令在事件网格命名空间上启用系统分配的托管标识:

az eventgrid namespace update --resource-group <resource group name> --name <namespace name> --identity "{type:systemassigned}" 

有关使用 Azure 门户配置系统和用户分配的标识的信息,请参阅为事件网格命名空间启用托管标识

创建 Azure Key Vault 帐户并上传服务器证书

  1. 使用以下命令创建 Azure Key Vault 帐户:

    az keyvault create --name "<your-unique-keyvault-name>" --resource-group "<resource group name>" --location "centraluseaup" 
    
  2. 使用以下命令将证书导入 Azure Key Vault

    az keyvault certificate import --vault-name "<your-key-vault-name>" -n "<cert name>" -f "<path to your certificate pem file> " 
    

    注意

    证书必须在 DNS 的使用者可选名称中包含域名。 有关详细信息,请参阅教程:在 Azure Key Vault 中导入证书

在 Azure Key Vault 中为命名空间的托管标识添加角色分配

需要使用以下步骤提供对命名空间的访问权限才能访问 Azure Key Vault 帐户:

  1. 使用以下命令获取事件网格命名空间系统托管标识主体 ID

    $principalId=(az eventgrid namespace show --resource-group <resource group name> --name <namespace name> --query identity.principalId -o tsv) 
    
  2. 获取 Azure 密钥保管库资源 ID。

    $keyVaultResourceId=(az keyvault show --resource-group <resource group name> --name <your key vault name> --query id -o tsv) 
    
  3. 在密钥保管库中为命名空间的托管标识添加角色分配。

    az role assignment create --role "Key Vault Certificate User" --assignee $principalId --scope $keyVaultResourceId 
    

    有关密钥保管库访问和门户体验的详细信息,请参阅使用 Azure 基于角色的访问控制提供对密钥保管库密钥、证书和机密的访问权限

在事件网格命名空间上配置自定义身份验证设置

在此步骤中,将使用 Azure 门户和 Azure CLI 在事件网格命名空间上配置自定义身份验证设置。 首先需要创建命名空间,然后使用以下步骤对其进行更新。

使用 Azure 门户

  1. Azure 门户中,导航到事件网格命名空间。

  2. 在“事件网格命名空间”页面中,选择左侧菜单上的“配置”。

  3. 在“自定义 JWT 身份验证”部分中,指定以下属性的值

    1. 选择“启用自定义 JWT 身份验证”

    2. 令牌颁发者:输入 MQTT 客户端提供的 JWT 令牌的颁发者声明的值。

    3. 选择“添加颁发者证书”

      显示事件网格命名空间的“配置”页的“自定义 JWT 身份验证”部分的屏幕截图。

    4. 在新页面中,指定以下属性的值。

      1. 证书 URL:所创建的 Azure 密钥保管库中颁发者证书的证书标识符。 可以改为选择“使用密钥保管库选择证书”,从订阅中选择证书和密钥保管库

      2. 标识:用于向密钥保管库进行身份验证以访问创建的颁发者证书的标识。

      3. 选择 添加

        显示“添加颁发者证书”页的屏幕截图。

  4. 返回“配置”页面,选择“应用”

    注意

    最多可以添加两个 iss 证书用于证书/密钥轮换。

使用 Azure CLI

使用以下命令通过自定义 JWT 身份验证配置更新命名空间。

az resource update --resource-type Microsoft.EventGrid/namespaces --api-version 2024-06-01-preview --ids /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/dummy-cd-test/providers/Microsoft.EventGrid/namespaces/dummy-cd-test2 --set properties.topicSpacesConfiguration.clientAuthentication='{\"customJwtAuthentication\":{\"tokenIssuer\":\"dmpypin-issuer\",\"issuerCertificates\":[{\"certificateUrl\":\"https://dummyCert-cd-test.vault.azure.net/certificates/dummy-cd-test/4f844b284afd487e9bba0831191087br1\",\"identity\":{\"type\":\"SystemAssigned\"}}]}}' 

JSON Web 令牌格式

Json Web 令牌分为 JWT 标头和 JWT 有效负载部分。

JWT 标头

标头必须至少包含 typalg 字段。 typ 必须始终是 JWSalg 必须始终是 RS256。 令牌标头必须如下所示:

{
    "typ": "JWT",
    "alg": "RS256"
}

JWT 有效负载

事件网格需要以下声明:isssubaudexpnbf

名称 描述
iss 颁发者。 JWT 中的值必须与事件网格命名空间配置中的颁发者匹配才能进行自定义 JWT 身份验证。
sub 主题。 值用作身份验证标识名称。
aud Audience。 值可以是字符串或字符串数组。 值必须包含标准事件网格命名空间主机名和/或该事件网格命名空间的自定义域(如果已配置)。 受众可以包含其他字符串,但至少需要其中一个字符串是标准事件网格命名空间主机名或该命名空间的自定义域。
exp Expiration。 JWT 到期时的 Unix 时间。
nbf 生效时间。 JWT 生效时的 Unit 时间。

事件网格将所有声明映射到客户端属性,前提是它们具有以下类型之一:int32stringarray of strings。 标准声明 isssubaudexpnbf 均从客户端属性中排除。 在以下 JWT 示例中,只有三个声明转换为客户端属性,num_attrstr_attrstr_list_attr,因为它们具有正确的类型 int32stringarray of strings。 incorrect_attr_1incorrect_attr_2incorrect_attr_3 不会转换为客户端属性,因为它们具有错误类型:floatarray of integersobject

{
    "iss": "correct_issuer",
    "sub": "d1",
    "aud": "testns.mqtt-broker-int.azure.net",
    "exp": 1712876224,
    "nbf": 1712869024,
    "num_attr": 1,
    "str_attr": "some string",
    "str_list_attr": [
        "string 1",
        "string 2"
    ],
    "incorrect_attr_1": 1.23,
    "incorrect_attr_2": [
        1,
        2,
        3
    ],
    "incorrect_attr_3": {
        "field": "value"
    }
}