.net Core X Forwarded Proto无法正常工作

Jos*_*osh 18 c# asp.net-mvc .net-core

我正在努力让我的.net核心1.1应用程序在负载均衡器后面工作并强制执行https.我的Startup.cs中有以下设置

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IServiceProvider serviceProvider, IOptions<Auth0Settings> auth0Settings)
{
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();


    var startupLogger = loggerFactory.CreateLogger<Startup>();


    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
        app.UseBrowserLink();
        startupLogger.LogInformation("In Development");
    }
    else
    {
        startupLogger.LogInformation("NOT in development");
        app.UseExceptionHandler("/Home/Error");
    }

    app.UseMiddleware<HttpsRedirectMiddleware>();
    app.UseForwardedHeaders(new ForwardedHeadersOptions
    {
        ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
    });`
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationScheme= CookieAuthenticationDefaults.AuthenticationScheme,
            AutomaticAuthenticate = true,
            AutomaticChallenge = true,
            CookieHttpOnly = true,
            SlidingExpiration = true
        });
Run Code Online (Sandbox Code Playgroud)

HttpsRedirectMiddleware用于验证LB具有X-Forwarded-Proto集合,它确实存在,并以https作为唯一值返回.当我访问该网站(https://myapp.somedomain.net)时,它知道我未经过身份验证并将我重定向到(http://myapp.somedomain.net/Account/Logon?ReturnUrl=%2f).它失去了SSL连接并切换回我的端口80..net核心文档说使用如下所示的"UseForwardedHeaders",这在我的情况下不起作用.当此切换发生时,控制台记录器没有来自中间件的任何错误或警告.

对于短期修复,我把它放在"UseForwardedHeaders"下面

    app.Use(async (context, next) =>
    {
        var xproto = context.Request.Headers["X-Forwarded-Proto"].ToString();
        if (xproto!=null && xproto.StartsWith("https", StringComparison.OrdinalIgnoreCase)){
            startupLogger.LogInformation("Switched to https");
            context.Request.Scheme = "https";
        }
        await next();

    });
Run Code Online (Sandbox Code Playgroud)

上面的作品很完美,但却是一个黑客.我想以正确的方式做到这一点.

Jos*_*osh 44

.net Core有转发标头的默认设置.对于IIS集成,它默认为127.0.0.1.在跟踪源代码后,您可以清除已知网络和已知代理以接受任何转发的请求.最好还是设置防火墙或将已知网络锁定到私有子网.

    var forwardingOptions = new ForwardedHeadersOptions()
    {
        ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
    };
    forwardingOptions.KnownNetworks.Clear(); //Loopback by default, this should be temporary
    forwardingOptions.KnownProxies.Clear(); //Update to include
    app.UseForwardedHeaders(forwardingOptions);
Run Code Online (Sandbox Code Playgroud)

  • 赞成,因为它帮助我解决了我的问题,谢谢!但值得指出的是:使用`.Clear()` 不应该*是一个长期的解决方案,因为它隐含地信任任何调用者。最好弄清楚您的反向代理将调用您的应用程序的地址或网络,并明确地将它们列入白名单。文档中的此页面有更多详细信息:https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-2.2#forwarded-headers-middleware -选项 (3认同)
  • 绝对地。那些 Clear() 行对我们产生了影响。 (2认同)
  • [文档](https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-2.2#forward-the -linux 和非 iis 反向代理的方案)。另一件可能导致问题的事情是以错误的顺序使用 `UseHttpsRedirection` 和 `UseForwardedHeaders` 中间件;就我而言,“UseForwardedHeaders”是第一个解决问题的。 (2认同)

Sun*_*ala 7

如果您使用负载平衡器,通常让负载平衡器终止 SSL 连接并通过 HTTP 将请求发送到您的应用程序。

这对我有用。我在 AWS 负载均衡器上使用 SSL 终止。

app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedProto
});
Run Code Online (Sandbox Code Playgroud)

这样做是使用 X-Forwarded-Proto 标头更新 Request.Scheme,以便所有重定向链接生成都使用正确的方案。

X-Forwarded-Proto:来自原始客户端和代理的方案。

  • 原作者有 `ForwardedHeaders = ForwardedHeaders.XForwardedFor | 示例中的 ForwardedHeaders.XForwardedProto` ,而此代码有所不同。根据我的经验,这是一个非常有意义的差异。事实上,这是我找到的唯一有效的答案。 (5认同)
  • 否决票是因为你基本上已经告诉了 OP 他已经知道的事情,如他的问题所示。 (3认同)