生产从未重定向到https,即使api已启用https重定向

时间:2019-03-26 13:29:28

标签: asp.net core hsts

我正在研究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,而两个环境上的代码都相同

2 个答案:

答案 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。