生产永远不会重定向到 https 即使 api 启用了 https 重定向

Production never redirect to https even api is enable for https redirect

我正在研究 asp.net 核心 2.1 API。 api 在所有环境中都按预期工作。最近我们为 HSTS headers 启用了它。所以在 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 找不到文件或目录。

'''''''''''''''''''' 在 Configure 方法中,我们有 '''''''''

app.UseHsts()
   .UseHttpsRedirection();

我希望在生产环境中我也应该得到 302 状态码而不是 404。

我是否遗漏了任何其他设置。为什么邮递员在生产环境中显示 404 而在开发环境中显示 302,当两个环境中的代码相同时

我发现 "http" 服务器上缺少绑定。添加 http 和 https 对我有用。

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。