强制实施 HTTPS 在 ASP.NET CoreEnforce HTTPS in ASP.NET Core

作者:Rick AndersonBy Rick Anderson

本文档演示如何:This document shows how to:

  • 要求所有请求使用 HTTPS。Require HTTPS for all requests.
  • 将所有 HTTP 请求重都定向到 HTTPS。Redirect all HTTP requests to HTTPS.

没有 API 可以防止客户端上的第一个请求发送敏感数据。No API can prevent a client from sending sensitive data on the first request.

警告

API 项目API projects

不要使用RequireHttpsAttribute接收敏感信息的 Web api。Do not use RequireHttpsAttribute on Web APIs that receive sensitive information. RequireHttpsAttribute 使用 HTTP 状态代码将从 HTTP 到 HTTPS 的浏览器重定向。RequireHttpsAttribute uses HTTP status codes to redirect browsers from HTTP to HTTPS. API 客户端可能无法理解或遵循从 HTTP 到 HTTPS 的重定向。API clients may not understand or obey redirects from HTTP to HTTPS. 此类客户端可能会通过 HTTP 发送的信息。Such clients may send information over HTTP. Web Api 应具有下列任一:Web APIs should either:

  • 不侦听 HTTP。Not listen on HTTP.
  • 关闭与状态代码 400 (错误请求) 的连接并不为请求提供服务。Close the connection with status code 400 (Bad Request) and not serve the request.

警告

API 项目API projects

不要使用RequireHttpsAttribute接收敏感信息的 Web api。Do not use RequireHttpsAttribute on Web APIs that receive sensitive information. RequireHttpsAttribute 使用 HTTP 状态代码将从 HTTP 到 HTTPS 的浏览器重定向。RequireHttpsAttribute uses HTTP status codes to redirect browsers from HTTP to HTTPS. API 客户端可能无法理解或遵循从 HTTP 到 HTTPS 的重定向。API clients may not understand or obey redirects from HTTP to HTTPS. 此类客户端可能会通过 HTTP 发送的信息。Such clients may send information over HTTP. Web Api 应具有下列任一:Web APIs should either:

  • 不侦听 HTTP。Not listen on HTTP.
  • 关闭与状态代码 400 (错误请求) 的连接并不为请求提供服务。Close the connection with status code 400 (Bad Request) and not serve the request.

HSTS 和 API 项目HSTS and API projects

默认 API 项目不包含HSTS因为 HSTS 通常是浏览器中唯一的说明。The default API projects don't include HSTS because HSTS is generally a browser only instruction. 其他调用方,例如电话或桌面应用程序,请执行遵循指令。Other callers, such as phone or desktop apps, do not obey the instruction. 即使在浏览器中,对通过 HTTP API 的单个经过身份验证的调用不安全网络上有风险。Even within browsers, a single authenticated call to an API over HTTP has risks on insecure networks. 安全的方法是 API 项目配置为只侦听并响应通过 HTTPS。The secure approach is to configure API projects to only listen to and respond over HTTPS.

要求使用 HTTPSRequire HTTPS

我们建议该生产 ASP.NET Core web 应用调用:We recommend that production ASP.NET Core web apps call:

  • HTTPS 重定向中间件 (UseHttpsRedirection) 将 HTTP 请求重定向到 HTTPS。HTTPS Redirection Middleware (UseHttpsRedirection) to redirect HTTP requests to HTTPS.
  • HSTS 中间件 (UseHsts) 发送给客户端的 HTTP 严格传输安全性协议 (HSTS) 标头。HSTS Middleware (UseHsts) to send HTTP Strict Transport Security Protocol (HSTS) headers to clients.

备注

反向代理配置中部署的应用程序允许代理在处理连接安全 (HTTPS)。Apps deployed in a reverse proxy configuration allow the proxy to handle connection security (HTTPS). 如果代理还处理 HTTPS 的重定向,则无需使用 HTTPS 重定向中间件。If the proxy also handles HTTPS redirection, there's no need to use HTTPS Redirection Middleware. 如果代理服务器还处理编写 HSTS 标头 (例如,本机 HSTS 支持 IIS 10.0 (1709) 或更高版本),HSTS 中间件不所需的应用程序。If the proxy server also handles writing HSTS headers (for example, native HSTS support in IIS 10.0 (1709) or later), HSTS Middleware isn't required by the app. 有关详细信息,请参阅退出的 HTTPS/HSTS 在项目创建For more information, see Opt-out of HTTPS/HSTS on project creation.

UseHttpsRedirectionUseHttpsRedirection

下面的代码调用UseHttpsRedirectionStartup类:The following code calls UseHttpsRedirection in the Startup class:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseCookiePolicy();

    app.UseMvc();
}

前面突出显示的代码:The preceding highlighted code:

我们建议使用临时重定向而不是永久重定向。We recommend using temporary redirects rather than permanent redirects. 链接缓存可以在开发环境中导致不稳定行为。Link caching can cause unstable behavior in development environments. 如果想要发送的永久重定向状态代码时该应用位于非开发环境,请参阅配置在生产环境中的永久重定向部分。If you prefer to send a permanent redirect status code when the app is in a non-Development environment, see the Configure permanent redirects in production section. 我们建议使用HSTS将信号发送到仅保护资源的客户端请求应发送到应用 (仅在生产中)。We recommend using HSTS to signal to clients that only secure resource requests should be sent to the app (only in production).

端口配置Port configuration

端口必须是可用于中间件将不安全的请求重定向到 HTTPS。A port must be available for the middleware to redirect an insecure request to HTTPS. 如果没有端口不可用:If no port is available:

  • 不会发生重定向到 HTTPS。Redirection to HTTPS doesn't occur.
  • 中间件将记录警告"无法确定重定向的 https 端口。"The middleware logs the warning "Failed to determine the https port for redirect."

指定使用任何以下方法之一的 HTTPS 端口:Specify the HTTPS port using any of the following approaches:

  • 设置HttpsRedirectionOptions.HttpsPortSet HttpsRedirectionOptions.HttpsPort.

  • 设置ASPNETCORE_HTTPS_PORT环境变量或https_port Web 主机配置设置:Set the ASPNETCORE_HTTPS_PORT environment variable or https_port Web Host configuration setting:

    密钥: https_portKey: https_port
    类型:string Type: string
    默认:未设置默认值。Default: A default value isn't set.
    设置使用UseSettingSet using: UseSetting
    环境变量:<PREFIX_>HTTPS_PORT (该前缀ASPNETCORE_使用时Web 主机。)Environment variable: <PREFIX_>HTTPS_PORT (The prefix is ASPNETCORE_ when using the Web Host.)

    配置时IWebHostBuilderProgram:When configuring an IWebHostBuilder in Program:

    public class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();
        }
    
        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseSetting("https_port", "8080")
                .UseStartup<Startup>();
    }
    
  • 指示具有安全方案使用的端口ASPNETCORE_URLS环境变量。Indicate a port with the secure scheme using the ASPNETCORE_URLS environment variable. 将服务器配置为环境变量。The environment variable configures the server. 中间件间接发现通过 HTTPS 端口IServerAddressesFeatureThe middleware indirectly discovers the HTTPS port via IServerAddressesFeature. 反向代理部署这种方法不起作用。This approach doesn't work in reverse proxy deployments.

  • 在开发中,在中设置 HTTPS URL launchsettings.jsonIn development, set an HTTPS URL in launchsettings.json. 使用 IIS Express 时,请启用 HTTPS。Enable HTTPS when IIS Express is used.

  • 配置 HTTPS URL 终结点的面向公众 edge 部署Kestrel服务器或HTTP.sys服务器。Configure an HTTPS URL endpoint for a public-facing edge deployment of Kestrel server or HTTP.sys server. 一个 HTTPS 端口应用使用。Only one HTTPS port is used by the app. 中间件发现通过端口IServerAddressesFeatureThe middleware discovers the port via IServerAddressesFeature.

备注

当应用在反向代理配置中,运行时IServerAddressesFeature不可用。When an app is run in a reverse proxy configuration, IServerAddressesFeature isn't available. 设置使用一种其他方法在本部分中所述的端口。Set the port using one of the other approaches described in this section.

当 Kestrel 或 HTTP.sys 用作面向公众的边缘服务器时,必须配置 Kestrel 或 HTTP.sys,若要在其上同时侦听:When Kestrel or HTTP.sys is used as a public-facing edge server, Kestrel or HTTP.sys must be configured to listen on both:

  • 其中重定向客户端的安全端口 (通常情况下,在生产和开发中的为 5001 的 443)。The secure port where the client is redirected (typically, 443 in production and 5001 in development).
  • 不安全端口 (通常情况下,在生产环境中为 80) 和 5000 开发中。The insecure port (typically, 80 in production and 5000 in development).

不安全的端口必须可由客户端按顺序应用接收不安全的请求,并将客户端重定向到安全的端口。The insecure port must be accessible by the client in order for the app to receive an insecure request and redirect the client to the secure port.

有关详细信息,请参阅Kestrel 终结点配置ASP.NET Core 中的 HTTP.sys Web 服务器实现For more information, see Kestrel endpoint configuration or ASP.NET Core 中的 HTTP.sys Web 服务器实现.

部署方案Deployment scenarios

客户端和服务器之间的所有防火墙也都必须打开的流量的通信端口。Any firewall between the client and server must also have communication ports open for traffic.

如果反向代理配置中将请求转发,则使用转发头中间件调用前 HTTPS 重定向中间件。If requests are forwarded in a reverse proxy configuration, use Forwarded Headers Middleware before calling HTTPS Redirection Middleware. 转发头中间件更新Request.Scheme,并使用X-Forwarded-Proto标头。Forwarded Headers Middleware updates the Request.Scheme, using the X-Forwarded-Proto header. 中间件允许重定向 Uri 和其他安全策略才能正常工作。The middleware permits redirect URIs and other security policies to work correctly. 转发头中间件不使用时后, 端应用程序可能不接收正确的方案和最终会在重定向循环。When Forwarded Headers Middleware isn't used, the backend app might not receive the correct scheme and end up in a redirect loop. 常见的最终用户错误消息是已发生过多的重定向。A common end user error message is that too many redirects have occurred.

部署到 Azure 应用服务时,请按照中的指导教程:将现有自定义 SSL 证书绑定到 Azure Web 应用When deploying to Azure App Service, follow the guidance in Tutorial: Bind an existing custom SSL certificate to Azure Web Apps.

选项Options

以下突出显示的代码调用AddHttpsRedirection配置中间件选项:The following highlighted code calls AddHttpsRedirection to configure middleware options:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    services.AddHsts(options =>
    {
        options.Preload = true;
        options.IncludeSubDomains = true;
        options.MaxAge = TimeSpan.FromDays(60);
        options.ExcludedHosts.Add("example.com");
        options.ExcludedHosts.Add("www.example.com");
    });

    services.AddHttpsRedirection(options =>
    {
        options.RedirectStatusCode = StatusCodes.Status307TemporaryRedirect;
        options.HttpsPort = 5001;
    });
}

调用AddHttpsRedirection只是用来更改的值HttpsPortRedirectStatusCodeCalling AddHttpsRedirection is only necessary to change the values of HttpsPort or RedirectStatusCode.

前面突出显示的代码:The preceding highlighted code:

在生产环境中配置永久重定向Configure permanent redirects in production

中间件默认为发送Status307TemporaryRedirect与所有重定向。The middleware defaults to sending a Status307TemporaryRedirect with all redirects. 如果想要发送的永久重定向状态代码,非开发环境中应用程序时,包装在对非开发环境的条件检查中的中间件的选项配置。If you prefer to send a permanent redirect status code when the app is in a non-Development environment, wrap the middleware options configuration in a conditional check for a non-Development environment.

配置时IWebHostBuilderStartup.cs:When configuring an IWebHostBuilder in Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    // IHostingEnvironment (stored in _env) is injected into the Startup class.
    if (!_env.IsDevelopment())
    {
        services.AddHttpsRedirection(options =>
        {
            options.RedirectStatusCode = StatusCodes.Status308PermanentRedirect;
            options.HttpsPort = 443;
        });
    }
}

HTTPS 重定向中间件另一种方法HTTPS Redirection Middleware alternative approach

使用 HTTPS 重定向中间件的替代方法 (UseHttpsRedirection) 是使用 URL 重写中间件 (AddRedirectToHttps)。An alternative to using HTTPS Redirection Middleware (UseHttpsRedirection) is to use URL Rewriting Middleware (AddRedirectToHttps). AddRedirectToHttps 此外可以设置的状态代码和端口时执行重定向。AddRedirectToHttps can also set the status code and port when the redirect is executed. 有关详细信息,请参阅URL 重写中间件For more information, see URL Rewriting Middleware.

当将重定向到 HTTPS 而无需其他重定向规则,我们建议使用 HTTPS 重定向中间件 (UseHttpsRedirection) 本主题中所述。When redirecting to HTTPS without the requirement for additional redirect rules, we recommend using HTTPS Redirection Middleware (UseHttpsRedirection) described in this topic.

RequireHttpsAttribute用于要求 HTTPS。The RequireHttpsAttribute is used to require HTTPS. [RequireHttpsAttribute] 可以修饰控制器或方法,也可以全局应用。[RequireHttpsAttribute] can decorate controllers or methods, or can be applied globally. 若要全局应用该属性,将以下代码添加到ConfigureServicesStartup:To apply the attribute globally, add the following code to ConfigureServices in Startup:

// Requires using Microsoft.AspNetCore.Mvc;
public void ConfigureServices(IServiceCollection services)
{
    services.Configure<MvcOptions>(options =>
    {
        options.Filters.Add(new RequireHttpsAttribute());
    });

前面突出显示的代码要求所有请求都使用HTTPS; 因此,HTTP 请求将被忽略。The preceding highlighted code requires all requests use HTTPS; therefore, HTTP requests are ignored. 以下突出显示的代码将所有 HTTP 请求重都定向到 HTTPS:The following highlighted code redirects all HTTP requests to HTTPS:

// 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);

有关详细信息,请参阅URL 重写中间件For more information, see URL Rewriting Middleware. 中间件还允许应用执行重定向时设置的状态代码或状态代码和端口。The middleware also permits the app to set the status code or the status code and the port when the redirect is executed.

全局需要 HTTPS (options.Filters.Add(new RequireHttpsAttribute());) 是最佳安全方案。Requiring HTTPS globally (options.Filters.Add(new RequireHttpsAttribute());) is a security best practice. 将应用[RequireHttps]属性设置为所有控制器/Razor 页面不会被视为与需要 HTTPS 全局一样安全。Applying the [RequireHttps] attribute to all controllers/Razor Pages isn't considered as secure as requiring HTTPS globally. 不能保证[RequireHttps]时添加新的控制器和 Razor 页面应用属性。You can't guarantee the [RequireHttps] attribute is applied when new controllers and Razor Pages are added.

HTTP 严格传输安全协议 (HSTS)HTTP Strict Transport Security Protocol (HSTS)

每个OWASPHTTP 严格传输安全性 (HSTS)是通过响应标头使用的 web 应用指定选择的安全增强功能。Per OWASP, HTTP Strict Transport Security (HSTS) is an opt-in security enhancement that's specified by a web app through the use of a response header. 浏览器支持 HSTS收到此标头:When a browser that supports HSTS receives this header:

  • 在浏览器将会阻止通过 HTTP 发送的任何通信的域的配置存储。The browser stores configuration for the domain that prevents sending any communication over HTTP. 在浏览器强制通过 HTTPS 进行的所有通信。The browser forces all communication over HTTPS.
  • 在浏览器可防止用户使用不受信任或无效的证书。The browser prevents the user from using untrusted or invalid certificates. 在浏览器禁用允许用户暂时信任此证书的提示。The browser disables prompts that allow a user to temporarily trust such a certificate.

因为由客户端强制执行 HSTS 它具有一些限制:Because HSTS is enforced by the client it has some limitations:

  • 客户端必须支持 HSTS。The client must support HSTS.
  • HSTS 要求至少一个成功的 HTTPS 请求能够建立 HSTS 策略。HSTS requires at least one successful HTTPS request to establish the HSTS policy.
  • 应用程序必须检查每个 HTTP 请求和重定向或拒绝的 HTTP 请求。The application must check every HTTP request and redirect or reject the HTTP request.

ASP.NET Core 2.1 或更高版本实现与 HSTSUseHsts扩展方法。ASP.NET Core 2.1 or later implements HSTS with the UseHsts extension method. 下面的代码调用UseHsts时应用不在开发模式:The following code calls UseHsts when the app isn't in development mode:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseCookiePolicy();

    app.UseMvc();
}

UseHsts 不建议在开发过程中由于 HSTS 设置高度可缓存的浏览器。UseHsts isn't recommended in development because the HSTS settings are highly cacheable by browsers. 默认情况下,UseHsts排除本地环回地址。By default, UseHsts excludes the local loopback address.

对于生产环境首次实现 HTTPS 设置初始HstsOptions.MaxAge为使用其中一个较小值TimeSpan方法。For production environments implementing HTTPS for the first time, set the initial HstsOptions.MaxAge to a small value using one of the TimeSpan methods. 设置的值从小时数不超过一天的以防到时需要还原 HTTP 到 HTTPS 基础结构。Set the value from hours to no more than a single day in case you need to revert the HTTPS infrastructure to HTTP. 确信 HTTPS 配置的可持续发展中后,增加 HSTS 最大期限值;常用的值为一年。After you're confident in the sustainability of the HTTPS configuration, increase the HSTS max-age value; a commonly used value is one year.

下面的代码:The following code:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    services.AddHsts(options =>
    {
        options.Preload = true;
        options.IncludeSubDomains = true;
        options.MaxAge = TimeSpan.FromDays(60);
        options.ExcludedHosts.Add("example.com");
        options.ExcludedHosts.Add("www.example.com");
    });

    services.AddHttpsRedirection(options =>
    {
        options.RedirectStatusCode = StatusCodes.Status307TemporaryRedirect;
        options.HttpsPort = 5001;
    });
}
  • 设置预加载严格传输安全性标头的参数。Sets the preload parameter of the Strict-Transport-Security header. 预加载不属于RFC HSTS 规范,但要预加载 HSTS 站点上执行全新安装的 web 浏览器支持。Preload isn't part of the RFC HSTS specification, but is supported by web browsers to preload HSTS sites on fresh install. 有关详细信息,请参阅 https://hstspreload.org/See https://hstspreload.org/ for more information.
  • 使includeSubDomain,这将 HSTS 策略应用到主机的子域。Enables includeSubDomain, which applies the HSTS policy to Host subdomains.
  • 显式将严格传输安全性标头的最大期限参数设置为 60 天。Explicitly sets the max-age parameter of the Strict-Transport-Security header to 60 days. 如果未设置,默认值为 30 天。If not set, defaults to 30 days. 请参阅最大期限指令有关详细信息。See the max-age directive for more information.
  • 添加example.com到主机以排除列表。Adds example.com to the list of hosts to exclude.

UseHsts 不包括以下环回主机:UseHsts excludes the following loopback hosts:

  • localhost:IPv4 环回地址。localhost : The IPv4 loopback address.
  • 127.0.0.1:IPv4 环回地址。127.0.0.1 : The IPv4 loopback address.
  • [::1]:IPv6 环回地址。[::1] : The IPv6 loopback address.

选择退出的 HTTPS/HSTS 在项目创建Opt-out of HTTPS/HSTS on project creation

在其中连接安全处理面向公众边缘网络的某些后端服务情况下,无需在每个节点上配置连接安全。In some backend service scenarios where connection security is handled at the public-facing edge of the network, configuring connection security at each node isn't required. Web 应用从 Visual Studio 中或从模板生成dotnet 新命令启用HTTPS 的重定向HSTSWeb apps generated from the templates in Visual Studio or from the dotnet new command enable HTTPS redirection and HSTS. 对于不需要这些方案的部署,你可以选择退出的 HTTPS/HSTS 时从模板创建的应用。For deployments that don't require these scenarios, you can opt-out of HTTPS/HSTS when the app is created from the template.

若要选择退出的 HTTPS/HSTS:To opt-out of HTTPS/HSTS:

取消选中配置为支持 HTTPS复选框。Uncheck the Configure for HTTPS check box.

新 ASP.NET Core Web 应用程序对话框中显示为 HTTPS 复选框未选定的配置。

信任在 Windows 和 macOS 上的 ASP.NET Core HTTPS 开发证书Trust the ASP.NET Core HTTPS development certificate on Windows and macOS

.NET core SDK 包括 HTTPS 开发证书。.NET Core SDK includes a HTTPS development certificate. 首次运行体验的一部分安装证书。The certificate is installed as part of the first-run experience. 例如,dotnet --info生成类似于以下输出:For example, dotnet --info produces output similar to the following:

ASP.NET Core
------------
Successfully installed the ASP.NET Core HTTPS Development Certificate.
To trust the certificate run 'dotnet dev-certs https --trust' (Windows and macOS only).
For establishing trust on other platforms refer to the platform specific documentation.
For more information on configuring HTTPS see https://go.microsoft.com/fwlink/?linkid=848054.

安装 .NET Core SDK 会将 ASP.NET Core HTTPS 开发证书安装到本地用户证书存储。Installing the .NET Core SDK installs the ASP.NET Core HTTPS development certificate to the local user certificate store. 已安装证书,但它具有不受信任。The certificate has been installed, but it's not trusted. 若要信任该证书执行一次性步骤,运行 dotnetdev-certs工具:To trust the certificate perform the one-time step to run the dotnet dev-certs tool:

dotnet dev-certs https --trust

下面的命令提供有关 dev-certs 工具的帮助:The following command provides help on the dev-certs tool:

dotnet dev-certs https --help

如何设置适用于 Docker 的开发人员证书How to set up a developer certificate for Docker

请参阅此 GitHub 问题See this GitHub issue.

信任适用于 Linux 的 Windows 子系统中的 HTTPS 证书Trust HTTPS certificate from Windows Subsystem for Linux

Windows 子系统用于 Linux (WSL) 生成 HTTPS 自签名的证书。若要配置要信任 WSL 证书的 Windows 证书存储:The Windows Subsystem for Linux (WSL) generates a HTTPS self-signed cert. To configure the Windows certificate store to trust the WSL certificate:

  • 运行以下命令以导出 WSL 生成证书: dotnet dev-certs https -ep %USERPROFILE%\.aspnet\https\aspnetapp.pfx -p <cryptic-password>Run the following command to export the WSL generated certificate: dotnet dev-certs https -ep %USERPROFILE%\.aspnet\https\aspnetapp.pfx -p <cryptic-password>

  • 在 WSL 窗口中,运行以下命令: ASPNETCORE_Kestrel__Certificates__Default__Password="<cryptic-password>" ASPNETCORE_Kestrel__Certificates__Default__Path=/mnt/c/Users/user-name/.aspnet/https/aspnetapp.pfx dotnet watch runIn a WSL window, run the following command: ASPNETCORE_Kestrel__Certificates__Default__Password="<cryptic-password>" ASPNETCORE_Kestrel__Certificates__Default__Path=/mnt/c/Users/user-name/.aspnet/https/aspnetapp.pfx dotnet watch run

    上述命令设置环境变量,因此 Linux 使用 Windows 受信任的证书。The preceding command sets the environment variables so Linux uses the Windows trusted certificate.

其他信息Additional information