使用托管标识订阅Function App到Event Grid主题时遇未授权错误
Event Grid主题发布失败导致Function App函数无法执行,未授权错误排查
已将Function App中的函数订阅至Event Grid主题,但出现发布失败问题,函数始终无法执行。已为托管标识配置Event Grid Data Sender和Event Grid Subscription Reader角色,Event Grid主题显示发布失败,按流程完成Function App授权后仍收到未授权错误。
函数代码
[FunctionName("broadcast")] public static async Task SendMessage( [EventGridTrigger] EventGridEvent eventGridEvent, [SignalR(HubName = "dttelemetry")] IAsyncCollector<SignalRMessage> signalRMessages, ILogger log) { bool broadcast_alert = false; bool broadcast_ledState = false; var telemetryMessage = new Dictionary<object, object>(); log.LogInformation("At top Broadcast"); var egevent = JsonConvert.DeserializeObject<Dictionary<object, object>>(eventGridEvent.Data.ToString()); if (eventGridEvent.EventType.Contains("telemetry")) { partId = "MachinePart1"; if (!b_debug_contractor) log.LogInformation("At broadcast - EvenType is Telemetry"); foreach (var telemetryProperty in egevent) { if (!b_debug_contractor) log.LogInformation("broadcast log at telemetry type:" + telemetryProperty.Key + " - " + telemetryProperty.Value); telemetryMessage.Add(telemetryProperty.Key, telemetryProperty.Value); } try { //log.LogInformation("Success adding broadcast target with args:" + telemetryMessage.ToString()); await signalRMessages.AddAsync( new SignalRMessage { Target = "TelemetryMessage", Arguments = new[] { telemetryMessage } //Arguments = new[] { output } }); log.LogWarning("Success Send telemetry transform data to H2"); } catch (Exception e) { log.LogInformation("Exception - Failed to send broadcast telemetry data to H2:" + e.Message); } } else if (eventGridEvent.EventType.Contains("Twin.Update")) { log.LogInformation("At broadcast - EvenType is Twin.Update"); foreach (var twinProperty in egevent) { if (!b_debug_contractor) log.LogInformation("broadcast log at Twin.Update type:" + twinProperty.Key + " - " + twinProperty.Value); if (twinProperty.Key.ToString() == "/Alert") { alert = (bool)twinProperty.Value; broadcast_alert = true; if (!b_debug_contractor) log.LogInformation("I've set broadcast_alert to " + broadcast_alert); } if (twinProperty.Key.ToString() == "/ledState") { ledState = (bool)twinProperty.Value; broadcast_ledState = true; if (!b_debug_contractor) log.LogInformation("I've set broadcast_ledState to " + broadcast_ledState); } } var propertyMessage = new Dictionary<object, object>(); if (broadcast_alert && broadcast_ledState) { propertyMessage.Add("PartID", partId); propertyMessage.Add("Alert", alert); propertyMessage.Add("LedState", ledState); if (!b_debug_contractor) log.LogInformation($"SingalRFunction - adding alert's PartID to: {partId}"); if (!b_debug_contractor) log.LogInformation($"SingalRFunction - adding alert to: {alert}"); if (!b_debug_contractor) log.LogInformation($"SingalRFunction - adding ledState to: {ledState}"); } else if (broadcast_alert && !broadcast_ledState) { propertyMessage.Add("PartID", partId); propertyMessage.Add("Alert", alert); if (!b_debug_contractor) log.LogInformation($"SingalRFunction - adding alert's PartID to: {partId}"); if (!b_debug_contractor) log.LogInformation($"SingalRFunction - adding alert to: {alert}"); } else if (!broadcast_alert && broadcast_ledState) { propertyMessage.Add("PartID", partId); propertyMessage.Add("LedState", ledState); if (!b_debug_contractor) log.LogInformation($"SingalRFunction - adding alert's PartID to: {partId}"); if (!b_debug_contractor) log.LogInformation($"SingalRFunction - adding ledState to: {ledState}"); } try { await signalRMessages.AddAsync( new SignalRMessage { Target = "PropertyMessage", Arguments = new[] { propertyMessage } }); log.LogWarning("Success Send Twin.Update transform data to H2"); } catch (Exception e) { log.LogInformation("Exception at SingalRFunction Twin.Update: " + e.Message); } } else if (eventGridEvent.EventType.Contains("broadcastTransform")) { var transformMessage = new Dictionary<object, object>(); log.LogInformation("At broadcast - EvenType is broadcastTransform"); foreach (var transformProperty in egevent) { if (!b_debug_contractor) log.LogInformation("broadcast log at broadcastTransform type:" + transformProperty.Key + " - " + transformProperty.Value); transformMessage.Add(transformProperty.Key, transformProperty.Value); } try { //log.LogInformation("Success adding broadcast target with args:" + telemetryMessage.ToString()); await signalRMessages.AddAsync( new SignalRMessage { Target = "TransformMessage", //Arguments = new[] { telemetryMessage } Arguments = new[] { transformMessage } }); log.LogWarning("Success Send broadcast transform data to H2."); } catch (Exception e) { log.LogInformation("Exception - Failed to send broadcastTransform data" + e.Message); } } else log.LogInformation("At Broadcast - Type not Recognized"); }
未授权错误日志
{ "time": "2023-01-04T08:25:27.3783585Z", "resourceId": "/SUBSCRIPTIONS/XXXX/RESOURCEGROUPS/MY-RG/PROVIDERS/MICROSOFT.EVENTGRID/TOPICS/eventgridtopicname", "category": "PublishFailures", "operationName": "Post", "message": "inputEventsCount=null, requestUri=https://eventgridtopicname.eastus-1.eventgrid.azure.net/api/events, publisherInfo=publisherName=eventgridtopicname.EASTUS-1.EVENTGRID.AZURE.NET, category=User, inputSchema=EventGridEvent, armResourceId=/subscriptions/XXX/resourceGroups/my-rg/providers/Microsoft.EventGrid/topics/eventgridtopicname, filteringPolicy:DnsHost, emitAuditLogs=False, drBoundary=WithinGeopair, regionCategory=Primary, isPublishBlockedDueToDr=False, httpStatusCode=Unauthorized, errorType=Unauthorized, errorMessage=The request authorization key is not authorized for eventgridtopicname.EASTUS-1.EVENTGRID.AZURE.NET." }
排查与解决建议
- 确认角色分配范围:检查Event Grid Data Sender和Event Grid Subscription Reader角色是否直接分配到Event Grid主题资源上,而非仅分配到父资源组或订阅(避免权限范围不匹配)
- 验证托管标识类型:如果使用用户分配托管标识,需确认Event Grid订阅时指定了正确的标识ID;若为系统分配标识,确保Function App的标识已启用
- 等待权限生效:Azure RBAC权限通常需要5-15分钟才能完全生效,等待足够时间后重试发布操作
- 检查主题验证方式:若Event Grid主题启用了访问密钥+Azure AD双重验证,需确保发布请求未误用访问密钥(托管标识场景应使用AD令牌而非密钥)
- 排查网络限制:如果Function App部署在虚拟网络中,需确认出站规则允许访问Event Grid服务端点(
eventgrid.azure.net),必要时添加服务端点或私有链接 - 查看详细诊断日志:在Event Grid主题的诊断设置中开启
PublishFailures日志,获取授权失败的具体细节(如令牌受众、标识ID是否匹配) - 验证标识令牌:使用Azure CLI以Function App标识身份运行
az account get-access-token --resource https://eventgrid.azure.net,检查返回令牌的aud(受众)是否为https://eventgrid.azure.net,oid(对象ID)是否与Function App托管标识的对象ID一致
内容的提问来源于stack exchange,提问作者Sergio Solorzano
相关产品推荐
相关产品推荐

