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

通过REST端点向Azure Application Insights发遥测的授权错误排查

关于Azure Application Insights遥测代理授权错误的排查与解决

当Azure Application Insights禁用本地身份验证后,前端无法直接上报遥测数据。为打通前后端日志链路,我在.NET Core API中实现了Telemetry Proxy Controller,但通过代理发送数据时收到Authorization not supported错误。

代理控制器代码

using System;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
using Azure.Core;
using Azure.Identity;
using IdentityModel.Client;
using Microsoft.ApplicationInsights;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;

namespace Reporting.API.Controllers
{
    [Route("api/[controller]")]
    [AllowAnonymous]
    [ApiController]
    public class TelemetryProxyController : ControllerBase
    {
        public TelemetryProxyController(IConfiguration configuration)
        {
            _client = new HttpClient();

            _configuration =
                configuration ?? throw new ArgumentNullException(nameof(configuration));
        }

        private static readonly string _appInsightsEndpoint =
            "https://dc.services.visualstudio.com/v2/track";
        private readonly HttpClient _client;
        private readonly IConfiguration _configuration;

        [HttpPost]
        public async Task Post(CancellationToken cancellationToken)
        {
            var credential = new DefaultAzureCredential();
            var scope = "https://monitor.azure.com//.default";

            var token = await credential.GetTokenAsync(
                new TokenRequestContext(new[] { scope }),
                cancellationToken
            );

            var request = new HttpRequestMessage
            {
                RequestUri = new Uri(_appInsightsEndpoint),
                Method = HttpMethod.Post,
                Content = new StreamContent(Request.Body)
            };

            foreach (var header in Request.Headers)
            {
                request.Content.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray());
            }

            request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token.Token);

            var response = await _client.SendAsync(request, cancellationToken);

            using var streamReader = new StreamReader(
                await response.Content.ReadAsStreamAsync(cancellationToken)
            );
            string result = await streamReader.ReadToEndAsync();
            await Response.WriteAsync(result, cancellationToken: cancellationToken);
        }
    }
}

遥测负载示例

[{"time":"2023-07-17T14:09:11.157Z","iKey":"00000000-0000-0000-0000-000000000000","name":"Microsoft.ApplicationInsights.2214063857374902a13cfbe145ee961c.Pageview","tags":{"ai.user.id":"XXXX","ai.session.id":"00000000-0000-0000-0000-000000000000","ai.device.id":"browser","ai.device.type":"Browser","ai.operation.name":"dashboard","ai.operation.id":"78bd3140ac724066a5d7ca41b78f5509","ai.internal.sdkVersion":"javascript:2.8.10","ai.internal.snippet":"-"},"data":{"baseType":"PageviewData","baseData":{"ver":2,"name":"next / dashboard","url":"https://next.ourcompany.nl/","duration":"00:00:00.623","properties":{"refUri":"","duration":"623"},"measurements":{},"id":"78bd3140ac724066a5d7ca41b78f5509"}}}]

错误响应

{"itemsReceived":1,"itemsAccepted":0,"errors":[{"index":0,"statusCode":400,"message":"Authorization not supported"}],"appId":"00000000-0000-0000-0000-000000000000"}

错误原因与解决方法

核心原因

你使用的传统遥测上报端点https://dc.services.visualstudio.com/v2/track仅支持基于Instrumentation Key(iKey)的身份验证,不兼容Azure AD令牌授权,即使令牌有效也会被端点拒绝。

解决步骤

  1. 切换到支持Azure AD的区域端点
    替换原端点为对应区域的专用授权端点,格式为:

    https://<region>.in.applicationinsights.azure.com/v2/track
    

    例如西欧区域的端点为https://westeurope.in.applicationinsights.azure.com/v2/track,可在Application Insights资源的"概述"页面获取对应区域地址。

  2. 修正权限范围格式
    原代码中scope多了一个斜杠,改为正确格式:

    var scope = "https://monitor.azure.com/.default";
    
  3. 优化请求头部转发逻辑
    避免转发前端所有头部导致冲突,仅保留必要的内容头部(如Content-Type):

    // 替换原头部循环逻辑
    request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
    
  4. 可选:移除负载中的iKey
    使用Azure AD授权时,iKey可省略,令牌会自动关联到对应资源;若保留iKey,需确保其与令牌关联的Application Insights资源一致。

修改后的核心代码片段

private static readonly string _appInsightsEndpoint =
    "https://westeurope.in.applicationinsights.azure.com/v2/track"; // 替换为你的区域端点

[HttpPost]
public async Task Post(CancellationToken cancellationToken)
{
    var credential = new DefaultAzureCredential();
    var scope = "https://monitor.azure.com/.default"; // 修正scope格式

    var token = await credential.GetTokenAsync(
        new TokenRequestContext(new[] { scope }),
        cancellationToken
    );

    var request = new HttpRequestMessage
    {
        RequestUri = new Uri(_appInsightsEndpoint),
        Method = HttpMethod.Post,
        Content = new StreamContent(Request.Body)
    };

    // 仅添加必要头部
    request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
    request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token.Token);

    var response = await _client.SendAsync(request, cancellationToken);

    using var streamReader = new StreamReader(
        await response.Content.ReadAsStreamAsync(cancellationToken)
    );
    string result = await streamReader.ReadToEndAsync();
    await Response.WriteAsync(result, cancellationToken: cancellationToken);
}

内容的提问来源于stack exchange,提问作者Joost

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 03:42:04