iis ASP.NET核心转发标头仅适用于最少的API

ruoxqz4g  于 2023-03-18  发布在  .NET
关注(0)|答案(1)|浏览(124)

正在解决转发头的问题,我已经创建了一个测试应用程序。该场景是一个托管在IIS上的ASP.NET核心MVC应用程序,该应用程序位于负载平衡器之后。问题是在应用程序中使用http://创建链接,而负载平衡器使用https://并将X-Forwarded-Proto头设置为https
在我的测试应用中,如果使用最小API进行如下设置,Forwarded Headers将正常工作,HttpContext.Request.Scheme将变为https

using Microsoft.AspNetCore.HttpOverrides;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedHeaders =
        ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
}

app.UseForwardedHeaders();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

但是,如果使用生产应用使用的旧ProgramStartup方法,Forwarded Headers将不再起作用,HttpContext.Request.Scheme将显示为http

using Microsoft.AspNetCore.HttpOverrides;

namespace TestApp;

public class Program
{
    public static void Main(string[] args)
    {
        IHost host = CreateHostBuilder(args).Build();

        host.Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args)
    {
        var builder = Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(builder =>
            {
                builder.UseStartup<Startup>();
            });

        return builder;
    }
}

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();
        services.Configure<ForwardedHeadersOptions>(options =>
        {
            options.ForwardedHeaders =
                ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
        });
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (!env.IsDevelopment())
        {
            app.UseExceptionHandler("/Home/Error");
        }

        app.UseForwardedHeaders();
        app.UseStaticFiles();
        app.UseRouting();
        app.UseAuthorization();

        app.UseEndpoints(e => e.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}")
        );
    }
}

我假设它们的工作方式完全相同。但是反复测试表明它们不是。我已经确保使用web.configASPNETCORE_FORWARDEDHEADERS_ENABLED环境变量设置为true。为什么只有最小API版本可以工作?

j91ykkif

j91ykkif1#

我让它工作了。我忘了提到这个应用使用OutOfProcess托管模型,这也是它为什么不工作的原因。修改ConfigureServices方法,将ForwardedHeadersOptions.ForwardLimit设置为2,并清除KnownNetworksKnownProxies列表,修复了它。

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.Configure<ForwardedHeadersOptions>(options =>
    {
        options.ForwardedHeaders =
            ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
        options.ForwardLimit = 2;
        options.KnownNetworks.Clear();
        options.KnownProxies.Clear();
    });
}

OutOfProcess托管IIS反向代理后的应用程序,该代理会用尽ForwardLimit的默认值1,但我不知道为什么它会使用问题中的顶级语句版本。WebApplication.CreateBuilderConfigureWebHostDefaults必须以不同的方式配置ForwardedHeadersOptions

注意:上述配置使转发标头在这种情况下工作,但在生产中应谨慎使用。

相关问题