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

使用GetDisplayUrl无法获取正确HTTPS协议的技术问题排查

问题:从HttpContext获取的URL协议始终为HTTP而非HTTPS

背景

我需要从HttpContext获取端点URL用于属性验证,要求URL完全匹配。但获取完整URL时,协议一直是HTTP而非HTTPS。测试时用Postman发起的是HTTPS请求,比如https://endpoint/id?access_token=xxx。

代码示例

public ProofKeyContextFactory Create(HttpContext httpContext)
{
    var endpointUrl = httpContext.Request
            .GetDisplayUrl()
            .ToUpperInvariant();
    _logger.LogInformation("Endpoint URL: {EndpointUrl}", endpointUrl);
}

查看Lens日志时,endpointUrl显示为HTTP://ENDPOINT/ID?ACCESS_TOKEN=XXX,并非预期的HTTPS。我尝试使用httpContext.Request.Scheme,但仍返回HTTP。

请问是什么原因导致SSL协议被识别为HTTP?

补充代码

ProofKeyContextFactory 完整实现

public class ProofKeyContextFactory
{
    private readonly ILogger<ProofKeyContextFactory> _logger;

    public ProofKeyContextFactory(ILogger<ProofKeyContextFactory> logger)
    {
        logger.ThrowIfNull();
        _logger = logger;
    }

    public ProofKeyContext Create(HttpContext httpContext)
    {
       var endpointUrl = httpContext.Request
                .GetDisplayUrl()
                .ToUpperInvariant();
        // 记录日志
        _logger.LogInformation("Endpoint URL: {EndpointUrl}", endpointUrl);

        // 赋值给密封记录类供后续使用
        return new ProofKeyContext(endpointUrl); 

    }
}

StartupExtension.cs 中的注册代码

private static IServiceCollection AddProofKeyContext(this IServiceCollection services)
{
    services.ThrowIfNull();

    services.AddHttpContextAccessor();
    services.AddScoped<ProofKeyContextFactory>();
    services.AddScoped<IProofKeyContext>(provider =>
    {
        var httpContextAccessor = provider.GetRequiredService<IHttpContextAccessor>();
        httpContextAccessor.HttpContext.ThrowIfNull();
        var factory = provider.GetRequiredService<ProofKeyContextFactory>();
        return factory.Create(httpContextAccessor.HttpContext);
    });

    return services;
}

原因及解决方案

这种情况最常见的原因是SSL终止在反向代理/负载均衡层,比如Nginx、AWS ALB、Azure应用网关这类组件。它们会先处理HTTPS请求,再用HTTP转发到后端的ASP.NET Core应用,导致应用直接拿到的是HTTP协议的请求。

解决方法1:配置转发头中间件

ASP.NET Core提供了ForwardedHeadersMiddleware,可以读取反向代理传递的转发头(如X-Forwarded-Proto),自动修正请求的Scheme。

在Program.cs(或Startup.cs)中添加以下配置:

var builder = WebApplication.CreateBuilder(args);

// 配置转发头,处理X-Forwarded-Proto等头信息
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedHeaders = 
        ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
    // 若反向代理是本地或可信IP,添加到KnownProxies或KnownNetworks
    // options.KnownProxies.Add(IPAddress.Parse("192.168.1.100"));
});

var app = builder.Build();

// 必须在其他中间件之前启用转发头中间件
app.UseForwardedHeaders();

// 其他中间件配置(如app.UseRouting()等)

解决方法2:手动读取转发头

如果不想用中间件,也可以手动从请求头中获取X-Forwarded-Proto的值来构造正确的URL:

public ProofKeyContext Create(HttpContext httpContext)
{
    var scheme = httpContext.Request.Headers.ContainsKey("X-Forwarded-Proto") 
        ? httpContext.Request.Headers["X-Forwarded-Proto"].ToString() 
        : httpContext.Request.Scheme;
    
    var endpointUrl = new UriBuilder(scheme, httpContext.Request.Host.Host, httpContext.Request.Host.Port ?? -1, 
        httpContext.Request.Path, httpContext.Request.QueryString.ToString())
        .Uri.ToString()
        .ToUpperInvariant();
    
    _logger.LogInformation("Endpoint URL: {EndpointUrl}", endpointUrl);
    return new ProofKeyContext(endpointUrl);
}

注意事项

  • 需确保反向代理配置正确,确实传递了X-Forwarded-Proto头,部分代理需要手动开启该配置(比如Nginx需添加proxy_set_header X-Forwarded-Proto $scheme;)。
  • 若应用部署在云服务(如Azure App Service、AWS Elastic Beanstalk),这类平台通常会自动处理转发头,只需启用ForwardedHeadersMiddleware即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 23:30:09