问题
当应用程序发布到 App Engine 时,我无法使从 HTTP 到 HTTPS 的自动重定向正常工作。
当我通过 example.com 访问该网站时,该网站被路由到 http://www.example.com并表明连接是不安全的。 当我通过https://www.example.com访问网站时然后,该网站将使用 google 管理的 SSL 进行正确保护。但是,不会发生从 HTTP 到 HTTPS 的自动重定向。
我还在日志查看器中收到一个错误,警告 Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionMiddleware 正在抛出无法确定用于重定向的 https 端口。
我遵循了 MSDN 的文档,只让它在本地工作,但当应用程序发布到 App Engine 时却没有。 https://learn.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$
我试过的是以下(一次只有一个)
- 将 HttpsRedirection 中间件添加到 ConfigureServices 方法。
最终导致应用无法访问(502 服务器错误)。
services.AddHttpsRedirection(options =>
{
options.RedirectStatusCode = StatusCodes.Status307TemporaryRedirect;
options.HttpsPort = 443;
});
- 将环境变量添加到 app.yaml
最终也无法访问应用程序(502 服务器错误)。
env_variables:
ASPNETCORE_HTTPS_PORT: "443"
- 在 Program.cs 中手动配置 HTTPS 端口
最终也无法访问应用程序(502 服务器错误)。
WebHost.CreateDefaultBuilder(args)
.UseSetting("https_port", "8080") // also return 502 when port is 443
- 在 ConfigureServices 方法中配置 ForwardedHeaderOptions 并在 Configure 方法中使用 ForwardedHeaderOptions。 https://learn.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();
- 在 Dockerfile 中手动公开端口 443 和 8080。
应用程序可访问,但没有自动 HTTP/HTTPS 重定向。我了解当 app.yaml 中的运行时设置为 aspnetcore。发布过程自动生成它自己的 Dockerfile,用于将应用程序部署到 App Engine。
EXPOSE 443
EXPOSE 8080
最佳答案
根据 Microsoft 上的提示,我创建了自己的中间件以查找“X-Forwarded-Proto” header 后,我以某种方式使它起作用和 App Engine文档。
Microsoft: Forwarded Headers Middleware must be enabled for an app to process forwarded headers with UseForwardedHeaders.
App Engine: SSL connections are terminated at the load balancer. Traffic from the load balancer is sent to the instance over an encrypted channel, and then forwarded to the application server over HTTP. The X-Forwarded-Proto header lets you understand if the origin request was HTTP or HTTPs.
Microsoft 要求在应用程序开始处理转发的 header 之前先激活中间件
因此在ConfigureServices方法中配置中间件选项
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
然后在Configure 方法中使用它,然后再做其他事情
app.UseForwardedHeaders();
然后编写自定义中间件,读取转发的 header 并重定向到 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);
}
});
最后Configure方法是这样的
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
关于c# - ASP.NET Core 2.1 在 App Engine 中没有 HTTP/HTTPS 重定向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52954158/