重定向到HTTPS

Wil*_*iam 35 c# https redirect middleware asp.net-core

建议的方法是将所有不安全的传入请求重定向到HTTPS.我是否需要编写中间件组件?如果是这样,我无法弄清楚如何获取服务器名称.

public class RedirectHttpMiddleware
{
    RequestDelegate _next;

    public RedirectHttpMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        if (context.Request.IsSecure)
            await _next(context);
        else
        {
            var server = "";  // How do I get the server name?
            context.Response.Redirect("https://" + server + context.Request.Path);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

vcs*_*nes 43

您可以使用自己的中间件类,但通常我只是在我的启动配置中执行以下操作:

app.Use(async (context, next) =>
{
    if (context.Request.IsHttps)
    {
        await next();
    }
    else
    {
        var withHttps = Uri.UriSchemeHttps + Uri.SchemeDelimiter + context.Request.Uri.GetComponents(UriComponents.AbsoluteUri & ~UriComponents.Scheme, UriFormat.SafeUnescaped);
        context.Response.Redirect(withHttps);
    }
});
Run Code Online (Sandbox Code Playgroud)

这样做只是抓取整个URL,查询字符串和所有,并用于GetComponents获取 URL中的方案之外的所有内容.然后将HTTPS方案添加到组件URL之前.

这将适用于完整的.NET Framework,对于ASP.NET Core,您可以执行以下操作:

app.Use(async (context, next) =>
{
    if (context.Request.IsHttps)
    {
        await next();
    }
    else
    {
        var withHttps = "https://" + context.Request.Host + context.Request.Path;
        context.Response.Redirect(withHttps);
    }
});
Run Code Online (Sandbox Code Playgroud)

这会将主机和路径附加到HTTPS方案.您可能还想添加其他组件,例如查询和哈希.

  • 我在这里得到"太多的重定向"错误.有什么想法吗? (2认同)

Jos*_*uch 16

对于.NET Core 2.0及更低版本(2.0的官方文档):

使用[RequireHttps]属性/过滤器.您可以对控制器执行此操作:

[RequireHttps]
public class AccountController {
}
Run Code Online (Sandbox Code Playgroud)

或者Startup.csConfigureServices方法中添加这个:

services.Configure<MvcOptions>(options =>
{
    options.Filters.Add(new RequireHttpsAttribute());
}
Run Code Online (Sandbox Code Playgroud)

另外,我只是想补充一点,vcsjones的答案也是正确的,但您需要确保在配置中尽早添加此代码,然后再导致任何其他导致重定向的中间件/代码.就我而言,我在添加Identity Framework中间件之前添加了它.

  • 使用MVC这样做的唯一微不足道的缺点是它仅将**应用于MVC.如果说,你在MVC之前有`services.UseStaticFiles()`(正如你应该的那样,静态内容不应该通过MVC管道),那么重定向就不会发生. (4认同)

Muh*_*eed 12

完整的答案是1号,但不要停在那里设置HTTPS,进行额外的步骤:

1 - 然后我们使用RequireHttpsAttribute重定向到HTTPS并在MVC选项中设置SSL端口.我们也在从launchSettings.json读取SSL端口,但我们只需要在开发模式下使用它.

2 - 用于AddAntiforgery在防伪令牌上要求HTTPS.

3 - 使用NWebsec.AspNetCore.MiddlewareNuGet包和UseHsts方法在站点上启用严格传输安全性(HSTS).不要忘记在下面添加预加载并将您的站点提交到HSTS预加载站点.更多信息在这里这里.

4 - 使用NWebsec.AspNetCore.MiddlewareNuGet包和UseHpkp方法在整个站点上启用公钥锁定(HPKP).请注意,如果您犯了这个错误,那么您基本上就是在做您的网站.更多信息在这里这里.

5 - 在任何使用的URL中包含https方案.内容安全策略(CSP) HTTP标头和子资源完整性(SRI)在某些浏览器中模仿该方案时效果不佳.最好明确HTTPS.例如

<script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.4/bootstrap.min.js"></script>
Run Code Online (Sandbox Code Playgroud)

6-使用ASP.NET MVC Boilerplate Visual Studio项目模板生成一个包含所有这些内置项目的项目.您还可以在GitHub上查看代码.

完成上述所有操作后,您的Startup课程应如下所示:

public class Startup
{
    private readonly int? sslPort;

    public Startup(IHostingEnvironment hostingEnvironment)
    {
        if (hostingEnvironment.IsDevelopment())
        {
            var launchConfiguration = new ConfigurationBuilder()
                .SetBasePath(hostingEnvironment.ContentRootPath)
                .AddJsonFile(@"Properties\launchSettings.json")
                .Build();
            // During development we won't be using port 443.
            this.sslPort = launchConfiguration.GetValue<int>("iisSettings:iisExpress:sslPort");
        }
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services
            .AddAntiforgery(options =>
            {
                options.RequireSsl = true;
            });
            .AddMvc(options =>
            {
                options.Filters.Add(new RequireHttpsAttribute());
                options.SslPort = sslPort;
            });
    }

    public void Configure(IApplicationBuilder application)
    {
        application
            .UseHsts(options => options.MaxAge(days: 18 * 7).IncludeSubdomains().Preload())
            .UseHpkp(options => options
                .Sha256Pins(
                    "Base64 encoded SHA-256 hash of your first certificate e.g. cUPcTAZWKaASuYWhhneDttWpY3oBAkE3h2+soZS7sWs=",
                    "Base64 encoded SHA-256 hash of your second backup certificate e.g. M8HztCzM3elUxkcjR2S5P4hhyBNf6lHkmjAHKhpGPWE=")
                .MaxAge(days: 18 * 7)
                .IncludeSubdomains())
            .UseCsp(options => options
                .UpgradeInsecureRequests(this.sslPort.HasValue ? this.sslPort.Value : 443))
            .UseMvc();
    }
}
Run Code Online (Sandbox Code Playgroud)