Function App基于RBAC向Event Grid发消息时遭遇未授权错误
问题场景
我有一个Function App,其中一个函数负责向Event Grid主题发送消息,同一Function App内的另一个函数订阅该主题。已配置RBAC权限,但发送消息时始终报未授权错误。
已完成的配置
- 启用Function App的系统分配托管标识
- 在订阅级别为该Function App分配了
Event Grid Sender角色(Event Grid主题位于同一订阅下) - 已在Event Grid主题的IAM角色分配中确认角色分配成功
发送代码
//Name of the endpoint of Event grid topic string topicEndpoint = transformAlgoSendRMessage_TopicEP; //Creating client to publish events to eventgrid topic EventGridPublisherClient client = new EventGridPublisherClient(new Uri(topicEndpoint), new DefaultAzureCredential()); //Creating a sample event with Subject, Eventtype, dataVersion and data EventGridEvent egEvent = new EventGridEvent("TransformTelemetry", "TransformAlgorithm.broadcastTransform", "1.0", machinePartTransformTelemetry); // Send the event try { await client.SendEventAsync(egEvent); if (b_debug_contractor) log.LogInformation("SendRTransformMessage sent transformdata - PosX:" + machinePartTransformTelemetry[1]); } catch (Exception e) { log.LogError("Failed to send SendRTransformMessage. " + e.Message); }
触发的未授权错误
[2022-11-25T08:00:45.646Z] Failed to send SendRTransformMessage. The principal associated with access token presented with the incoming request does not have permission to send data to /subscriptions/MySubscriptionID/resourceGroups/myresourcegroup/providers/Microsoft.EventGrid/topics/functionappname. Report 'e9595a36-8420-4466-b91a-801fbfcf605d:4:11/25/2022 8:00:48 AM (UTC)' to our forums for assistance or raise a support ticket.
[2022-11-25T08:00:45.646Z] Status: 401 (The principal associated with access token presented with the incoming request does not have permission to send data to /subscriptions/mySubscriptionID/resourceGroups/myresourcegroup/providers/Microsoft.EventGrid/topics/myfunctionappname. Report 'e9595a36-8420-4466-b91a-801fbfcf605d:4:11/25/2022 8:00:48 AM (UTC)' to our forums for assistance or raise a support ticket.)
[2022-11-25T08:00:45.647Z] ErrorCode: Unauthorized
[2022-11-25T08:00:45.647Z]
[2022-11-25T08:00:45.647Z] Content:
[2022-11-25T08:00:45.648Z] {
[2022-11-25T08:00:45.648Z] "error": {
[2022-11-25T08:00:45.649Z] "code": "Unauthorized",
[2022-11-25T08:00:45.649Z] "message": "The principal associated with access token presented with the incoming request does not have permission to send data to /subscriptions/mySubscriptionID/resourceGroups/myresourcegroup/providers/Microsoft.EventGrid/topics/myfunctionappname. Report 'e9595a36-8420-4466-b91a-801fbfcf605d:4:11/25/2022 8:00:48 AM (UTC)' to our forums for assistance or raise a support ticket.",
[2022-11-25T08:00:45.650Z] "details": [{
[2022-11-25T08:00:45.650Z] "code": "Unauthorized",
[2022-11-25T08:00:45.650Z] "message": "The principal associated with access token presented with the incoming request does not have permission to send data to /subscriptions/mySubscriptionID/resourceGroups/myresourcegroup/providers/Microsoft.EventGrid/topics/myfunctionappname. Report 'e9595a36-8420-4466-b91a-801fbfcf605d:4:11/25/2022 8:00:48 AM (UTC)' to our forums for assistance or raise a support ticket."
额外尝试
曾尝试使用密钥凭据发送消息,但Azure无法识别该密钥。
解决步骤
1. 调整角色分配的作用域
虽然在订阅级别分配了Event Grid Sender角色,但权限继承可能存在延迟或问题。建议直接在Event Grid主题资源级别分配该角色:
- 进入Event Grid主题的IAM页面
- 添加角色分配,选择
Event Grid Sender角色,指定Function App的系统分配标识为主体 - 保存后等待5-10分钟让权限生效(Azure RBAC权限通常需要几分钟同步)
2. 验证DefaultAzureCredential的身份
DefaultAzureCredential在Function App环境中应优先使用系统分配标识,可添加日志确认获取的身份是否正确:
var credential = new DefaultAzureCredential(); var token = await credential.GetTokenAsync(new Azure.Core.TokenRequestContext(new[] { "https://eventgrid.azure.net/.default" })); log.LogInformation($"当前身份OID: {token.Claims.FirstOrDefault(c => c.Type == "oid")?.Value}");
将日志中的OID与Function App“标识”页面的系统分配标识OID对比,确认是否一致。
3. 检查Event Grid主题的访问设置
进入Event Grid主题的“访问控制(IAM)”->“概述”,确认访问设置:
- 如果启用了仅允许Azure AD身份验证,确保角色分配正确
- 若需兼容密钥验证,可暂时切换为“允许Azure AD和访问密钥”,但推荐长期使用RBAC
4. 确认函数运行环境
确保函数运行在Azure托管环境中(而非本地调试),代码中未硬编码其他凭据,避免干扰DefaultAzureCredential的身份获取。
密钥验证失败的修复
若使用密钥时提示“密钥不存在”,需:
- 从Event Grid主题的“访问密钥”页面获取有效密钥(两个密钥均可使用)
- 代码中使用
AzureKeyCredential初始化客户端:
EventGridPublisherClient client = new EventGridPublisherClient(new Uri(topicEndpoint), new AzureKeyCredential("你的主题访问密钥"));
内容的提问来源于stack exchange,提问作者Sergio Solorzano

