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

本地调试正常的Graph头像方法部署IIS生产环境报Bearer认证错误

问题描述

应用集成Microsoft Identity作为外部登录提供程序,本地环境可通过保存的bearer token正常调用Microsoft Graph拉取用户头像,生产环境部署在运行IIS 10的Windows Server 2019服务器上,对应功能触发异常。
核心调用代码如下:

public async Task<string> GetMicrosoftGraphPhotoAsync(string token)
{
    var clientId = _configuration.GetSection("AzureAd").GetSection("ClientId").Value;
    var vaultUrl = _configuration.GetSection("AzureAd").GetSection("KeyVaultUrl").Value;
    var certName = _configuration.GetSection("AzureAd").GetSection("KeyVaultCertificateName").Value;
    var client = new CertificateClient(vaultUri: new Uri(vaultUrl), credential: new DefaultAzureCredential());
    var cert = await client.DownloadCertificateAsync(certName);

    var tenantId = _configuration.GetSection("AzureAd").GetSection("TenantId").Value;
    var cca = ConfidentialClientApplicationBuilder
        .Create(clientId)
        .WithTenantId(tenantId)
        .WithCertificate(cert.Value)
        .Build();

    var scopes = new[] { "https://graph.microsoft.com/.default" };
    var authProvider = new DelegateAuthenticationProvider(async (request) =>
    {
        var assertion = new UserAssertion(token);
        var result = await cca.AcquireTokenOnBehalfOf(scopes, assertion).ExecuteAsync();

        request.Headers.Authorization =
            new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", result.AccessToken);
    });

    GraphServiceClient graphClient = new GraphServiceClient(authProvider);
    var stream = await graphClient.Me.Photos["120x120"]
        .Content
        .Request()
        .GetAsync();

    if (stream == null)
    {
        return null!;
    }

    // 从流生成图片
    var image = SixLabors.ImageSharp.Image.Load(stream, out var format);
    return image.ToBase64String(format);
}
故障报错信息

生产环境触发异常核心信息:

Bearer token authentication is not permitted for non TLS protected (https) endpoints.

从错误堆栈可以定位,异常抛出点是CertificateClient向Azure Key Vault发起请求拉取证书的环节,并非调用Microsoft Graph接口的环节。

排查方向与解决方案

首先明确:该报错和终端用户访问IIS站点是否启用HTTPS没有直接关联,报错是Azure SDK的内置安全拦截机制触发的——SDK检测到应用作为客户端向外发送携带Bearer令牌的请求时,目标地址不是HTTPS协议,为了防止令牌泄露直接终止了请求。

按优先级从高到低排查:

  • 核对生产环境Key Vault配置地址格式
    检查生产环境配置文件、环境变量、IIS配置项中存储的AzureAd:KeyVaultUrl值,必须为https://<你的Key Vault名称>.vault.azure.net/格式,禁止使用HTTP前缀。这是该类问题最高发的原因,本地调试配置正确但生产环境发布时填错地址的情况非常普遍。
  • 检查服务器出站代理配置
    如果生产服务器配置了系统级、应用级出站HTTP代理,访问Azure Key Vault的请求被代理转发到HTTP链路,会触发SDK的安全拦截。直接在生产服务器上用浏览器访问Key Vault的HTTPS地址,确认地址栏显示锁形标识、证书有效,不存在代理劫持降级到HTTP连接的情况。
  • 检查Key Vault防火墙与网络配置
    如果Key Vault开启了网络访问限制,拦截了生产服务器的公网出口IP,部分场景下Key Vault返回的重定向响应会指向HTTP地址,SDK跟随重定向到非HTTPS端点时就会抛出该错误。临时将生产服务器出口IP加入Key Vault的允许访问列表,测试功能是否恢复。
  • 检查应用代码是否开启了不安全HTTP允许开关
    排查代码中是否存在AppContext.SetSwitch("Azure.Experimental.EnableInsecureHttp", true);配置,该配置允许SDK向HTTP地址发送令牌,但部分版本SDK在开启该配置后仍会在特定链路触发非HTTPS拦截报错,生产环境必须删除该配置,强制所有Azure服务请求走HTTPS。
  • 清理代码冗余变量
    原代码中定义的未被使用的DefaultAzureCredential冗余变量虽然不会直接触发该报错,但容易引发配置混淆,直接删除即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 17:54:36