当应用发布到App Engine时,我无法从HTTP自动重定向到HTTPS才能正常工作。
当我通过example.com访问该网站时,该网站被路由到http://www.example.com,并显示该连接不安全。当我通过https://www.example.com访问该网站时,该网站便由Google管理的SSL正确地保护了。但是,不会发生从HTTP到HTTPS的自动重定向。
我还在Log Viewer中收到一个错误,警告Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionMiddleware抛出失败,无法确定重定向的https端口。
我遵循了MSDN上的文档,仅使它在本地运行,但未在将应用发布到App Engine时使用。 https://docs.microsoft.com/zh-cn/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$
最终导致应用无法访问(502服务器错误)。
services.AddHttpsRedirection(options =>
{
options.RedirectStatusCode = StatusCodes.Status307TemporaryRedirect;
options.HttpsPort = 443;
});
也导致应用无法访问(502服务器错误)。
env_variables:
ASPNETCORE_HTTPS_PORT: "443"
也导致应用无法访问(502服务器错误)。
WebHost.CreateDefaultBuilder(args)
.UseSetting("https_port", "8080") // also return 502 when port is 443
可访问该应用程序,但无法自动进行HTTP / HTTPS重定向。
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
app.UseForwardedHeaders();
可访问该应用程序,但无法自动进行HTTP / HTTPS重定向。据我了解,当app.yaml中的运行时设置为aspnetcore时。发布过程会自动生成它自己的Dockerfile,该文件用于将应用程序部署到App Engine。
EXPOSE 443
EXPOSE 8080
根据Microsoft和App Engine文档上的提示,创建自己的中间件以查找“ X-Forwarded-Proto ”标头后,以某种方式使它起作用。
Microsoft:转发的标头中间件必须启用,应用才能使用UseForwardedHeaders处理转发的标头。
App Engine: SSL连接在负载均衡器处终止。来自负载平衡器的流量通过加密通道发送到实例,然后通过HTTP转发到应用程序服务器。X-Forwarded-Proto标头可让你了解原始请求是HTTP还是HTTP。
Microsoft要求在应用开始处理转发的标头之前首先激活中间件
因此,在ConfigureServices方法中配置中间件选项
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
并在其他方法之前在Configure方法中使用它
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);
}
});
最后,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
这是一个很好的答案,对我有用。我想补充一下,您应该使用
context.Response.Redirect(https, true)
而不是,context.Response.Redirect(https)
因为前者将使用HTTP状态代码301而不是302进行重定向。为此,Google建议使用301:support.google.com/webmasters/answer/6073543非常感谢你做的这些!我一直在与这个斗争。仍然有点烦,听起来这里的说明docs.microsoft.com/zh-cn/aspnet/core/host-and-deploy / ...应该涵盖此用例,而无需自定义重定向。