.net Core X Forwarded Proto не работает

Я работаю над тем, чтобы мое приложение.net core 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
        });

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();

    });

Вышеизложенное работает отлично, но является взломом. Я хотел бы сделать это правильно.

Ответ 1

.net Core имеет набор по умолчанию для переадресованных заголовков. По умолчанию используется 127.0.0.1 для интеграции с IIS. После отслеживания исходного кода вы можете очистить Известные сети и Известные прокси, чтобы принимать любые перенаправленные запросы. Тем не менее, лучше всего настроить брандмауэр или заблокировать известные сети в частной подсети.

    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);

Обновление для сетевого ядра dotnet 2.x. Установите IP-адрес вашего прокси/балансировщика нагрузки или частной сети после устранения проблемы. Это предотвращает обход вашего прокси/балансировщика нагрузки и подделку перенаправленных заголовков.

services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardLimit = 2;
    options.KnownProxies.Add(IPAddress.Parse("192.168.1.5")); //Replace with IP of your proxy/load balancer
    options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("192.168.1.0"),24));;
}) //192.168.1.0/24 allows any from 192.168.1.1-254;

https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-2.2#forwarded-headers-middleware-options

Ответ 2

Если вы используете балансировщик нагрузки, обычно балансировка нагрузки прерывает SSL-соединение и отправляет запрос в ваше приложение по HTTP.

Это сработало для меня. Я использую завершение SSL на AWS Load Balancer.

app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedProto
});

Это обновляет Request.Scheme заголовком X-Forwarded-Proto, так что при генерации всех переадресаций используется правильная схема.

X-Forwarded-Proto: схема от оригинального клиента и прокси.