我正在研究asp.net core 2.1 API。该API在所有环境下均按预期工作。最近,我们为HSTS标头启用了它。因此在startup.cs-> ConfigureServices方法中的代码下面添加了
services.AddHsts(options =>
{
options.Preload = true;
options.IncludeSubDomains = true;
});
services.AddHttpsRedirection(options =>
{
options.RedirectStatusCode = StatusCodes.Status301MovedPermanently;
options.HttpsPort = int.Parse(443);
});
当我检查邮递员在开发环境中对http请求的响应时 它给了我302重定向状态代码。符合预期
但是在针对http请求的生产中, 它给我404文件或目录未找到。
''''''''''''''''''''' 在配置方法中,我们有 '''''''''
app.UseHsts()
.UseHttpsRedirection();
我希望在Production上也应该获得302状态代码,而不是404。
我是否错过任何其他设置。为什么邮递员在生产环境中显示404,但在开发环境中显示302,而两个环境上的代码都相同
答案 0 :(得分:0)
我发现服务器上缺少“ http”绑定。对我来说,将HTTP和https一起添加即可。
答案 1 :(得分:0)
似乎ASP.NET Core具有一些逻辑来检测您是否配置了正确的HTTPS侦听器。但是,如果您没有启用某些其他配置(例如IISIntegration
或自HTTPS托管),则ASP.NET Core不可能知道Web服务器支持HTTPS。
因此,我们在GitHub上阅读了UseHTTPSRedirection
的源代码,并构建了自己的中间件以将所有流量重定向到HTTPS。像这样:
namespace YourApp.Middlewares
{
public class EnforceHttpsMiddleware
{
private readonly RequestDelegate _next;
private readonly IConfiguration _configuration;
private readonly ILogger _logger;
public EnforceHttpsMiddleware(
RequestDelegate next,
IConfiguration configuration,
ILogger<EnforceHttpsMiddleware> logger)
{
_next = next;
_configuration = configuration;
_logger = logger;
}
public async Task Invoke(HttpContext context)
{
// Use this bool to trigger HSTS.
var hsts = false;
if (hsts && !context.Response.Headers.ContainsKey("Strict-Transport-Security"))
{
context.Response.Headers.Add("Strict-Transport-Security", "max-age=15552001; includeSubDomains; preload");
}
else if (!context.Request.IsHttps)
{
_logger.LogWarning("Insecure HTTP request handled! Redirecting the user...");
await HandleNonHttpsRequest(context);
}
else
{
await _next.Invoke(context);
}
}
protected virtual async Task HandleNonHttpsRequest(HttpContext context)
{
if (!string.Equals(context.Request.Method, "GET", StringComparison.OrdinalIgnoreCase))
{
context.Response.StatusCode = StatusCodes.Status403Forbidden;
}
else
{
var optionsAccessor = context.RequestServices.GetRequiredService<IOptions<MvcOptions>>();
var request = context.Request;
var host = request.Host;
if (optionsAccessor.Value.SslPort.HasValue && optionsAccessor.Value.SslPort > 0)
{
host = new HostString(host.Host, optionsAccessor.Value.SslPort.Value);
}
else
{
host = new HostString(host.Host);
}
var newUrl = string.Concat(
"https://",
host.ToUriComponent(),
request.PathBase.ToUriComponent(),
request.Path.ToUriComponent(),
request.QueryString.ToUriComponent());
context.Response.Redirect(newUrl, permanent: true);
}
}
}
}
并像这样使用您的中间件:
public static IApplicationBuilder UseEnforceHttps(this IApplicationBuilder app)
{
return app.UseMiddleware<EnforceHttpsMiddleware>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseEnforceHttps();
}
app.UseStaticFiles();
app.UseAuthentication();
app.UseMvcWithDefaultRoute();
}
仅在生产环境中,此中间件将帮助您处理HTTP请求并将其重定向到HTTPS。