You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用托管标识订阅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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 18:05:32