本文介绍如何使用 OAuth 2.0 JSON Web 令牌通过 Azure 事件网格命名空间进行身份验证。
Azure 事件网格的 MQTT 代理支持 OAuth 2.0 JWT 身份验证,使客户端能够使用任何标识提供者颁发的 JSON Web 令牌(除了Microsoft Entra ID 之外)通过事件网格命名空间进行连接和身份验证。
先决条件
若要对命名空间使用 OAuth 2.0 JWT 身份验证,需要满足以下先决条件:
- 可以颁发 JSON Web 令牌的标识提供者。
- CA 证书,其中包括用于验证公钥证书(直接上传)的客户端令牌 (Key Vault) 或 PEM 文件的公钥。
简要步骤
若要对命名空间使用 OAuth 2.0 JWT 身份验证,请执行以下步骤:
创建命名空间并配置其子资源。
在事件网格命名空间上启用托管标识。
按照以下步骤在事件网格命名空间上配置 OAuth 2.0 身份验证设置:
- 创建一个 Azure Key Vault 帐户,该帐户托管包含公钥的 CA 证书,并在 Key Vault 中为命名空间的托管标识添加角色分配。
- 或者将公钥证书的 PEM 文件上传到命名空间。
客户端可以使用标识提供者提供的令牌连接到事件网格命名空间。
创建命名空间并配置其子资源
按照快速入门:使用 Azure 门户在事件网格命名空间上发布和订阅 MQTT 消息创建命名空间并配置其子资源。 跳过证书和客户端创建步骤,因为客户端标识来自提供的令牌。 客户端属性基于客户端令牌中的自定义声明。 客户端属性用于客户端组查询、主题模板变量和路由扩充配置。
在事件网格命名空间上启用托管标识
命名空间使用托管标识访问 Azure 密钥保管库实例,以获取自定义域的服务器证书。 使用以下命令在事件网格命名空间上启用系统分配的托管标识:
az eventgrid namespace update --resource-group <resource group name> --name <namespace name> --identity "{type:systemassigned}"
有关使用 Azure 门户配置系统和用户分配的标识的信息,请参阅为事件网格命名空间启用托管标识。
在事件网格命名空间 -Key 保管库上配置 OAuth 2.0 JWT 身份验证设置
首先,创建 Azure Key Vault 帐户,上传服务器证书,并在密钥保管库上为命名空间的托管标识分配适当的角色。 然后,使用 Azure 门户或 Azure CLI 在事件网格命名空间上配置自定义身份验证设置。 首先需要创建命名空间,然后使用以下步骤对其进行更新。
创建 Azure Key Vault 帐户并上传服务器证书
使用以下命令创建 Azure Key Vault 帐户:
az keyvault create --name "<your-unique-keyvault-name>" --resource-group "<resource group name>" --___location "centraluseuap"
使用以下命令将证书导入 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 帐户:
使用以下命令获取事件网格命名空间系统托管标识主体 ID
$principalId=(az eventgrid namespace show --resource-group <resource group name> --name <namespace name> --query identity.principalId -o tsv)
获取 Azure 密钥保管库资源 ID。
$keyVaultResourceId=(az keyvault show --resource-group <resource group name> --name <your key vault name> --query id -o tsv)
在密钥保管库中为命名空间的托管标识添加角色分配。
az role assignment create --role "Key Vault Certificate User" --assignee $principalId --scope $keyVaultResourceId
有关密钥保管库访问和门户体验的详细信息,请参阅使用 Azure 基于角色的访问控制提供对密钥保管库密钥、证书和机密的访问权限。
使用 Azure 门户配置身份验证
在 Azure 门户中,导航到事件网格命名空间。
在“事件网格命名空间”页面中,选择左侧菜单上的“配置”。
在“自定义 JWT 身份验证”部分中,指定以下属性的值:
返回“配置”页面,选择“应用”。
注意
最多可以添加两个
iss
证书用于证书/密钥轮换。
使用 Azure CLI
使用以下命令通过自定义 JWT 身份验证配置更新命名空间。
az resource update \
--resource-type Microsoft.EventGrid/namespaces \
--api-version 2024-06-01-preview \
--ids /subscriptions/1111a1a1-bb2b-cc3c-dd4d-ffffee5e5e5e/resourceGroups/sample-rg/providers/Microsoft.EventGrid/namespaces/sample-namespace \
--set properties.topicSpacesConfiguration.clientAuthentication='{
\"customJwtAuthentication\":{
\"tokenIssuer\":\"sample-issuer\",
\"issuerCertificates\":[
{
\"certificateUrl\":\"https://sample-vault.vault.azure.net/certificates/sample-cert/12345abcdef67890\",
\"identity\":{
\"type\":\"UserAssigned\",
\"userAssignedIdentity\":\"/subscriptions/1111a1a1-bb2b-cc3c-dd4d-ffffee5e5e5e/resourceGroups/sample-rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/sample-identity\"
}
}
]
}
}'
JSON Web 令牌格式
JSON Web 令牌需要具有 JWT 标头、JWT 有效负载和 JWT 签名部分。
JWT 标头
标头必须至少包含 typ
和 alg
字段。 typ
必须始终是 JWS
,alg
必须始终是 RS256
。 令牌标头必须如下所示:
{
"typ": "JWT",
"alg": "RS256"
}
JWT 有效负载
事件网格需要以下声明:iss
、sub
、aud
、exp
和 nbf
。
名称 | 描述 |
---|---|
iss |
颁发者。 JWT 中的值必须与事件网格命名空间配置中的颁发者匹配才能进行自定义 JWT 身份验证。 |
sub |
主题。 值用作身份验证标识名称。 |
aud |
Audience。 值是字符串数组。 值必须包含标准事件网格命名空间主机名和/或该事件网格命名空间的自定义域(如果已配置)。 受众可以包含其他字符串,但至少需要其中一个字符串是标准事件网格命名空间主机名或该命名空间的自定义域。 |
exp |
Expiration。 JWT 到期时的 Unix 时间。 |
nbf |
生效时间。 JWT 生效时的 Unit 时间。 |
事件网格将所有声明映射到客户端属性,前提是它们具有以下类型之一:int32
、string
和 array of strings
。 标准声明 iss
、sub
、aud
、exp
和 nbf
均从客户端属性中排除。 在以下 JWT 示例中,只有三个声明转换为客户端属性,num_attr
、str_attr
和 str_list_attr
,因为它们具有正确的类型 int32
、string
和 array of strings
。 incorrect_attr_1
、incorrect_attr_2
和 incorrect_attr_3
不会转换为客户端属性,因为它们具有错误类型:float
、array of integers
和 object
。
{
"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"
}
}
在事件网格命名空间上配置 OAuth 2.0 JWT 身份验证设置 - 直接上传
在此步骤中,将使用 Azure 门户和 Azure CLI 在事件网格命名空间上配置自定义 JWT 身份验证设置。 首先需要创建命名空间,然后使用以下步骤对其进行更新。
使用 Azure 门户
- 在 Azure 门户中,导航到事件网格命名空间。
- 在“事件网格命名空间”页上,选择左侧菜单中的配置。
- 在“自定义 JWT 身份验证”部分中,指定以下属性的值:
- 在新页面中,指定以下属性的值。
- 返回“配置”页面,选择“应用”。
使用 Azure CLI
使用以下命令使用 OAuth 2.0 JWT 身份验证配置更新命名空间。
az eventgrid namespace update \
--resource-group <resource-group-name> \
--name <namespace-name> \
--api-version 2024-12-15-preview \
--set customJwtAuthenticationSettings='{
"tokenIssuer": "issuer-name",
"encodedIssuerCertificates": [
{
"kid": "key1",
"encodedCertificate": "-----BEGIN CERTIFICATE-----\n<certificate-in-PEM-format>\n-----END CERTIFICATE-----"
}
]
}
- 将
<resource-group-name>
、<namespace-name>
、<___location>
、<key-vault-name>
、<certificate-name>
和<certificate-in-PEM-format>
替换为你的实际值。 - encodedCertificate 值必须包含 PEM 格式的完整证书和公钥,包括标头(
"-----BEGIN CERTIFICATE-----", "-----END CERTIFICATE----, ``-----BEGIN PUBLIC KEY----- and -----END PUBLIC KEY-----
)。 - 确保提供的公钥证书有效且受标识提供者信任。
- 如果证书已轮换或过期,请定期更新 encodedIssuerCertificate。
JSON Web 令牌格式
JSON Web 令牌需要具有 JWT 标头、JWT 有效负载和 JWT 签名部分。
事件网格需要以下声明:iss
、sub
、aud
、exp
和 nbf
。
kid
是可选的。 如果存在,则使用匹配kid
的证书进行验证。- 未用作属性的标准声明列表 -
iss
、sub
aud
exp
nbf
、 、 。iat
jti
- 所有具有正确数据类型的声明项(包括适合 int32 的数字、字符串和字符串数组)都用作属性。 在此示例中
num_attr_pos
,num_attr_neg
str_attr
str_list_attr
声明具有正确的数据类型,并用作属性。 - 在此示例中
bool_attr
num_attr_to_big
,num_attr_float
obj_attr
声明的数据类型不正确,不能用作属性。
{
"typ": "JWT",
"alg": "RS256",
"kid": "keyId1"
}.{
"iss": "some-issuer",
"sub": "device1",
"aud": "event-grid-namespace.ts.eventgrid.azure.net",
"exp": 1770426501,
"nbf": 1738886901,
"bool_attr": true,
"num_attr_pos": 1,
"num_attr_neg": -1,
"num_attr_to_big": 9223372036854775807,
"num_attr_float": 1.23,
"str_attr": "str_value",
"str_list_attr": [
"str_value_1",
"str_value_2"
],
"obj_attr": {
"key": "value"
}
}