C# ASP.NET Core 2.1在应用程序引擎中没有HTTP/HTTPS重定向 问题
当应用程序发布到应用程序引擎时,我无法使从HTTP到HTTPS的自动重定向正常工作C# ASP.NET Core 2.1在应用程序引擎中没有HTTP/HTTPS重定向 问题,c#,asp.net,google-app-engine,asp.net-core,google-cloud-platform,C#,Asp.net,Google App Engine,Asp.net Core,Google Cloud Platform,当应用程序发布到应用程序引擎时,我无法使从HTTP到HTTPS的自动重定向正常工作 EXPOSE 443 EXPOSE 8080 当我通过example.com访问该网站时,该网站被路由到并显示连接不安全。 当我通过该网站访问该网站时,谷歌管理的SSL将正确保护该网站。但是,不会发生从HTTP到HTTPS的自动重定向 我在日志查看器中还收到一个错误,警告Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionMiddleware无法确定重定向的htt
EXPOSE 443
EXPOSE 8080
当我通过example.com访问该网站时,该网站被路由到并显示连接不安全。
当我通过该网站访问该网站时,谷歌管理的SSL将正确保护该网站。但是,不会发生从HTTP到HTTPS的自动重定向
我在日志查看器中还收到一个错误,警告Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionMiddleware无法确定重定向的https端口
我遵循了MSDN的文档,只在本地运行,但在应用程序发布到AppEngine时不运行。
这是Program.cs。基本上是项目模板的默认值
public static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
return WebHost.CreateDefaultBuilder(args)
.CaptureStartupErrors(true)
.UseStartup<Startup>();
}
我尝试了以下方法(一次只能尝试一种)
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
app.UseForwardedHeaders();
不知何故,我在创建了自己的中间件之后实现了这一点,该中间件根据本文和文档中的提示查找“X-Forwarded-Proto”头 Microsoft:必须启用转发头中间件,应用程序才能使用UseForwardedHeaders处理转发头 应用程序引擎:SSL连接在负载平衡器处终止。来自负载平衡器的流量通过加密通道发送到实例,然后通过HTTP转发到应用程序服务器。X-Forwarded-Proto头允许您了解原始请求是HTTP还是HTTPs Microsoft要求在应用程序开始处理转发的头文件之前首先激活中间件 因此,在ConfigureServices方法中配置中间件选项
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
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);
}
});
然后编写自定义中间件,读取转发的头并重定向到HTTPS(包括查询)
在中配置方法
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
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();
}
现在导航到直接重定向我可以在
启动中手动设置方案。在使用任何类型的中间件之前配置
:
app.Use((context, next) =>
{
context.Request.Scheme = "https";
return next();
});
这就是我的工作原理(代码位于Startup.cs中):
public void配置服务(IServiceCollection服务)
{
配置(选项=>
{
options.ForwardedHeaders=
ForwardedHeaders.XForwardedFor|
ForwardedHeaders.XForwardedProto;
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
});
services.AddHttpsRedirection(opt=>opt.HttpsPort=443);
//为清晰起见,代码已删除
}
public void配置(IApplicationBuilder应用程序、IWebHostEnvironment环境)
{
if(env.IsDevelopment())
{
//为清晰起见,代码已删除
}
其他的
{
//为清晰起见,代码已删除
app.UseHsts();
}
app.UseForwardedHeaders();
app.UseHttpsRedirection();
//为清晰起见,代码已删除
}
这是一个很好的答案,对我很有用。我想补充一点,您应该使用context.Response.Redirect(https,true)
而不是context.Response.Redirect(https)
,因为前者将使用HTTP状态代码301而不是302进行重定向。谷歌建议使用301来达到这个目的:非常感谢你!我一直在为此奋斗。仍然有点恼火,听起来这里的说明应该涵盖这个用例,而不需要定制重定向。
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);
}
});
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();
}
app.Use((context, next) =>
{
context.Request.Scheme = "https";
return next();
});
public void ConfigureServices(IServiceCollection services)
{
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor |
ForwardedHeaders.XForwardedProto;
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
});
services.AddHttpsRedirection(opt => opt.HttpsPort = 443);
// code removed for clarity
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
// code removed for clarity
}
else
{
// code removed for clarity
app.UseHsts();
}
app.UseForwardedHeaders();
app.UseHttpsRedirection();
// code removed for clarity
}