ASP.NET Core 2.1 нет перенаправления HTTP / HTTPS в App Engine - PullRequest
0 голосов
/ 23 октября 2018

Проблема

Я не смог настроить правильное перенаправление с HTTP на HTTPS для правильной работы при публикации приложения в App Engine.

Когда я захожу на веб-сайт в примере .com сайт перенаправлен на http://www.example.com и показывает, что соединение незащищено.Когда я захожу на сайт через https://www.example.com, сайт корректно защищается с помощью управляемого Google SSL.Однако автоматическое перенаправление с HTTP на HTTPS не происходит.

Insecured connection

Я также получил ошибку в Log Viewer, предупреждающую о том, что Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionMiddlewareНе удалось определить порт HTTPS для перенаправления.

enter image description here

Я следовал документации MSDN и получал ее только локально, но не когдаприложение опубликовано в App Engine.https://docs.microsoft.com/en-us/aspnet/core/security/enforcing-ssl?view=aspnetcore-2.1&tabs=visual-studio

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory logger)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
    }
    else
    {
        app.UseStatusCodePages();
        app.UseExceptionHandler("/Error");
        app.UseHsts(); // This was added by the template
    }

    app.UseHttpsRedirection(); // This was added by the template
    app.UseStaticFiles();
    app.UseCookiePolicy();
    app.UseAuthentication();
    app.UseMvc();
}

Вот Program.cs.В основном по умолчанию из шаблона проекта

public static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
    return WebHost.CreateDefaultBuilder(args)
        .CaptureStartupErrors(true)
        .UseStartup<Startup>();
}

app.yaml, использованный для развертывания

runtime: aspnetcore
env: flexible
automatic_scaling:
  min_num_instances: 1
  max_num_instances: 20
  cpu_utilization:
    target_utilization: 0.8
readiness_check:
  path: "/readinesscheck"
  check_interval_sec: 5
  timeout_sec: 4
  failure_threshold: 2
  success_threshold: 2
  app_start_timeout_sec: 300
liveness_check:
  path: "/livenesscheck"
  check_interval_sec: 30
  timeout_sec: 4
  failure_threshold: 2
  success_threshold: 2
skip_files:
  - node_modules/
  - wwwroot/src/vendor/
  - ^(.*/)?.*\.pdb$
  - ^(.*/)?.*\.log$

Я попробовал следующее (только по одному за раз)

  1. AddHttpsRedirection Middleware для метода ConfigureServices.

Что привело к недоступности приложения (502 Ошибка сервера).

services.AddHttpsRedirection(options =>
{
    options.RedirectStatusCode = StatusCodes.Status307TemporaryRedirect;
    options.HttpsPort = 443;
});
Добавить переменную среды в app.yaml

В результате приложение было недоступно (ошибка 502 сервера).

env_variables:
   ASPNETCORE_HTTPS_PORT: "443"
Ручная настройка HTTPS-порта в Program.cs

Кроме того, в результате приложение стало недоступным (502 Ошибка сервера).

WebHost.CreateDefaultBuilder(args)
    .UseSetting("https_port", "8080") // also return 502 when port is 443
Настройте ForwardedHeaderOptions в методе ConfigureServices и используйте ForwardedHeaderOptions в методе Configure.https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-2.1#other-proxy-server-and-load-balancer-scenarios

Приложение доступно, но без автоматического перенаправления HTTP / HTTPS.

services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedHeaders = 
        ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});

app.UseForwardedHeaders();
Предоставление доступа к портам 443 и 8080 в Dockerfile.

Приложение доступно, но без автоматического перенаправления HTTP / HTTPS.Я понимаю, что когда время выполнения в app.yaml установлено на aspnetcore .Процесс публикации автоматически сгенерировал свой собственный Dockerfile, который используется для развертывания приложения в App Engine.

EXPOSE 443
EXPOSE 8080

1 Ответ

0 голосов
/ 23 октября 2018

Каким-то образом я заставил это работать после создания собственного промежуточного программного обеспечения, которое ищет заголовок « X-Forwarded-Proto » согласно этой подсказке на Microsoft и App Engine документация.

Microsoft: Промежуточное программное обеспечение перенаправленных заголовков должно быть включено, чтобы приложение могло обрабатывать перенаправленные заголовки с помощью UseForwardedHeaders.

App Engine: SSL-соединения прекращаются на балансировщике нагрузки.Трафик от балансировщика нагрузки отправляется экземпляру по зашифрованному каналу, а затем направляется на сервер приложений по HTTP.Заголовок X-Forwarded-Proto позволяет понять, был ли исходный запрос HTTP или HTTP.

Microsoft требует, чтобы промежуточное программное обеспечение было сначала активировано до запуска приложения для обработки перенаправленных заголовков

Настроить параметры промежуточного программного обеспечения в ConfigureServices метод

services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedHeaders = 
        ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});

и использовать его в Настроить метод перед чем-либо еще

app.UseForwardedHeaders();

Затем написатьпользовательское промежуточное ПО, которое считывает перенаправленные заголовки и перенаправляет на HTTPS, включая запросы.

В Настройка Метод

app.Use(async (context, next) =>
{
    if (context.Request.IsHttps || context.Request.Headers["X-Forwarded-Proto"] == Uri.UriSchemeHttps)
    {
        await next();
    }
    else
    {
        string queryString = context.Request.QueryString.HasValue ? context.Request.QueryString.Value : string.Empty;
        var https = "https://" + context.Request.Host + context.Request.Path + queryString;
        context.Response.Redirect(https);
    }
});

В конце концов Настройка метод выглядит следующим образом

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    app.UseForwardedHeaders();
    app.Use(async (context, next) =>
    {
        if (context.Request.IsHttps || context.Request.Headers["X-Forwarded-Proto"] == Uri.UriSchemeHttps)
        {
            await next();
        }
        else
        {
            string queryString = context.Request.QueryString.HasValue ? context.Request.QueryString.Value : string.Empty;
            var https = "https://" + context.Request.Host + context.Request.Path + queryString;
            context.Response.Redirect(https);
        }
    });

    if (env.IsDevelopment())
    {
        // code removed for clarity
    }
    else
    {
        // code removed for clarity
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    // code removed for clarity
    app.UseMvc();
}

Теперь перейдите на example.com и перенаправьте меня напрямую https://www.example.com

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...