Kestrel HTTPS POST 在生产环境中导致 400 错误请求状态代码(ASP.NET 核心 2.x)
Kestrel HTTPS POST results in a 400 bad request status code when in production (ASP.NET Core 2.x)
我关注了这篇文章https://docs.microsoft.com/en-us/aspnet/core/security/enforcing-ssl
我完全按照文章建议设置的地方
// Requires using Microsoft.AspNetCore.Mvc;
public void ConfigureServices(IServiceCollection services)
{
services.Configure<MvcOptions>(options =>
{
options.Filters.Add(new RequireHttpsAttribute());
});
和
// Requires using Microsoft.AspNetCore.Rewrite;
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
var options = new RewriteOptions()
.AddRedirectToHttps();
app.UseRewriter(options);
在所有浏览器上发送 GET 请求时,这似乎工作正常。但是,当它遇到 POST 请求时,我得到一个 400 状态代码,但没有太多说明是什么原因造成的——奇怪的是,这个问题在 DEBUG 模式下不会发生。
如果我使用 Edge 或 IE,则不会发生此错误。当我使用 Chrome 或 POSTMAN 时,我得到 400 状态代码。
奇怪的是,如果我使用 POSTMAN,并且我将 POST 请求更改为使用 HTTP,而不是 HTTPS,我会得到 200 (OK) 响应。所以,我认为上面的文章存在某种问题,但我没有找到解决方案。
有人对这个问题有任何经验或见解吗?
我从未使用过 ASP.NET 核心重写器,但查看其代码,它使用标准 Response.Redirect()
方法 - https://github.com/aspnet/BasicMiddleware/blob/9814f3bfbcf3a11dc86c4047fbfc2fe48744f96c/src/Microsoft.AspNetCore.Rewrite/Internal/RedirectToHttpsRule.cs#L33
此 Redirect() 方法只能 returning HTTP 301 或 302 代码。
浏览器很可能会遵循此重定向,但它可能会决定在没有任何数据的情况下使用 GET 或 POST。
我建议在浏览器开发工具中启用 preserve log
并检查实际发生的情况。这个post描述的很好-https://scotthelme.co.uk/report-uri-journey-to-a-permanent-redirect/
长话短说,你需要 HTTP 307 或 308。AddRedirectToHttps
有一个可选的状态代码参数,它没有在代码中的任何地方使用(看起来像 ASP.NET Core 上的一个错误)
您可能需要编写自己的代码来重定向 HTTP 请求。
我在我的一个项目中遇到了同样的问题,为了简单起见,我决定 return HTTP 403 Forbidden for non-GET HTTP requests
编辑:
我查看了 AddRedirectToHttps
的错误分支。实际上它似乎能够 returning 不同的状态代码然后只是 301 和 302,所以你应该能够轻松地将状态代码配置为参数。
我关注了这篇文章https://docs.microsoft.com/en-us/aspnet/core/security/enforcing-ssl
我完全按照文章建议设置的地方
// Requires using Microsoft.AspNetCore.Mvc;
public void ConfigureServices(IServiceCollection services)
{
services.Configure<MvcOptions>(options =>
{
options.Filters.Add(new RequireHttpsAttribute());
});
和
// Requires using Microsoft.AspNetCore.Rewrite;
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
var options = new RewriteOptions()
.AddRedirectToHttps();
app.UseRewriter(options);
在所有浏览器上发送 GET 请求时,这似乎工作正常。但是,当它遇到 POST 请求时,我得到一个 400 状态代码,但没有太多说明是什么原因造成的——奇怪的是,这个问题在 DEBUG 模式下不会发生。
如果我使用 Edge 或 IE,则不会发生此错误。当我使用 Chrome 或 POSTMAN 时,我得到 400 状态代码。
奇怪的是,如果我使用 POSTMAN,并且我将 POST 请求更改为使用 HTTP,而不是 HTTPS,我会得到 200 (OK) 响应。所以,我认为上面的文章存在某种问题,但我没有找到解决方案。
有人对这个问题有任何经验或见解吗?
我从未使用过 ASP.NET 核心重写器,但查看其代码,它使用标准 Response.Redirect()
方法 - https://github.com/aspnet/BasicMiddleware/blob/9814f3bfbcf3a11dc86c4047fbfc2fe48744f96c/src/Microsoft.AspNetCore.Rewrite/Internal/RedirectToHttpsRule.cs#L33
此 Redirect() 方法只能 returning HTTP 301 或 302 代码。
浏览器很可能会遵循此重定向,但它可能会决定在没有任何数据的情况下使用 GET 或 POST。
我建议在浏览器开发工具中启用 preserve log
并检查实际发生的情况。这个post描述的很好-https://scotthelme.co.uk/report-uri-journey-to-a-permanent-redirect/
长话短说,你需要 HTTP 307 或 308。AddRedirectToHttps
有一个可选的状态代码参数,它没有在代码中的任何地方使用(看起来像 ASP.NET Core 上的一个错误)
您可能需要编写自己的代码来重定向 HTTP 请求。
我在我的一个项目中遇到了同样的问题,为了简单起见,我决定 return HTTP 403 Forbidden for non-GET HTTP requests
编辑:
我查看了 AddRedirectToHttps
的错误分支。实际上它似乎能够 returning 不同的状态代码然后只是 301 和 302,所以你应该能够轻松地将状态代码配置为参数。