在 ASP.NET Core 中强制使用 HTTPS
作者:David Galvan 和 Rick Anderson
本文介绍如何处理:
- 对所有请求都要求使用 HTTPS。
- 将所有 HTTP 请求重定向到 HTTPS。
任何 API 都不能阻止客户端在第一次请求时发送敏感数据。
警告
API 项目
请勿在接收敏感信息的 Web API 上使用 RequireHttpsAttributeRequireHttpsAttribute。 RequireHttpsAttribute
使用 HTTP 状态代码将浏览器从 HTTP 重定向到 HTTPS。 API 客户端可能不理解或不遵循从 HTTP 到 HTTPS 的重定向。 此类客户端可以通过 HTTP 发送信息。 Web API 应该执行以下操作之一:
- 不侦听 HTTP。
- 关闭状态码为 400(错误请求)的连接并且不处理请求。
若要在 API 中禁用 HTTP 重定向,请设置 ASPNETCORE_URLS
环境变量或使用 --urls
命令行标志。 有关详细信息,请参阅 Andrew Lock 撰写的在 ASP.NET Core 中使用多个环境和为 ASP.NET Core 应用设置 URL 的 8 种方法。
HSTS 和 API 项目
默认 API 项目不包括 HSTS,因为 HSTS 通常是浏览器专用的指令。 其他调用方(例如电话或桌面应用)不遵循该指令。 即使在浏览器中,通过 HTTP 对 API 的单个经过身份验证的调用在不安全的网络中也会有风险。 安全的方法是将 API 项目配置为仅通过 HTTPS 进行侦听和响应。
HTTP 重定向到 HTTPS 会导致 CORS 预检请求出现 ERR_INVALID_REDIRECT
在 CORS 预检请求时,使用由 UseHttpsRedirection 重定向到 HTTPS 的 HTTP 请求终结点失败,错误为 ERR_INVALID_REDIRECT
。
API 项目可以拒绝 HTTP 请求,而不是使用 UseHttpsRedirection
将请求重定向到 HTTPS。
需要 HTTPS
建议生产 ASP.NET Core web 应用使用:
- HTTPS 重定向中间件 (UseHttpsRedirection) 将 HTTP 请求重定向到 HTTPS。
- HSTS 中间件 (UseHsts) 将 HTTP 严格传输安全协议 (HSTS) 标头发送到客户端。
注意
在反向代理配置中部署的应用允许代理来处理连接安全性 (HTTPS)。 如果该代理也处理 HTTPS 重定向,则无需使用 HTTPS 重定向中间件。 如果代理服务器也处理写入 HSTS 标头(例如,IIS 10.0 (1709) 或更高版本中的本机 HSTS 支持),则应用不需要使用 HSTS 中间件。 有关详细信息,请参阅项目创建时选择退出 HTTPS/HSTS。
UseHttpsRedirection
以下代码调用 Program.cs
文件中的 UseHttpsRedirection:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
上述突出显示的代码:
- 使用默认 HttpsRedirectionOptions.RedirectStatusCode (Status307TemporaryRedirect) 。
- 除非被
ASPNETCORE_HTTPS_PORT
环境变量或 IServerAddressesFeature 替代,否则使用默认 HttpsRedirectionOptions.HttpsPort (null)。
建议使用临时重定向,而不使用永久性重定向。 链接缓存会导致开发环境中的行为不稳定。 如果希望在应用处于非开发环境时发送永久性重定向状态代码,请参阅在生产环境中配置永久性重定向部分。 建议使用 HSTS 向客户端发出信号,即应仅将安全资源请求发送到应用(仅在生产环境中)。
端口配置
中间件必须有可用的端口才能将不安全的请求重定向到 HTTPS。 如果没有可用的端口:
- 不会重定向到 HTTPS。
- 中间件记录“无法确定用于重定向的 https 端口”警告。
使用以下任一方法指定 HTTPS 端口:
设置
https_port
主机设置:在主机配置中。
通过设置
ASPNETCORE_HTTPS_PORT
环境变量。通过在
appsettings.json
中添加顶级条目:{ "https_port": 443, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*" }
使用 ASPNETCORE_URLS 环境变量指示使用安全方案的端口。 该环境变量配置服务器。 中间件通过 IServerAddressesFeature 间接发现 HTTPS 端口。 此方法在反向代理部署中不起作用。
ASP.NET Core Web 模板在
Properties/launchsettings.json
中为 Kestrel 和 IIS Express 设置 HTTPS URL。launchsettings.json
仅在本地计算机上使用。为 Kestrel 服务器或 HTTP.sys 服务器的面向公众的边缘部署配置 HTTPS URL 终结点。 该应用仅使用一个 HTTPS 端口。 中间件通过 IServerAddressesFeature 发现该端口。
注意
当应用在反向代理配置中运行时,IServerAddressesFeature 不可用。 使用本部分中所述的其他方法之一设置端口。
Edge 部署
当 Kestrel 或 HTTP.sys 用作面向公众的边缘服务器时,必须将 Kestrel 或 HTTP.sys 配置为对这两者进行侦听:
- 重定向客户端的安全端口(通常在生产环境中为 443,在开发环境中为 5001)。
- 不安全的端口(通常在生产环境中为 80,在开发环境中为 5000)。
客户端必须可以访问不安全的端口,以便应用接收不安全的请求并将客户端重定向到安全端口。
有关详细信息,请参阅 Kestrel终结点配置或 ASP.NET Core 中的 HTTP.sys Web 服务器实现。
部署方案
客户端和服务器之间的任何防火墙还必须打开通信端口供流量使用。
如果在反向代理配置中转发请求,请在调用 HTTPS 重定向中间件之前使用转接头中间件。 转接头中间件使用 X-Forwarded-Proto
标头更新 Request.Scheme
。 使用该中间件,重定向 URI 和其他安全策略可以正常工作。 如果不使用转接头中间件,后端应用可能无法接收到正确的方案并最终进入重定向循环。 常见的最终用户错误消息是发生了太多重定向。
部署到 Azure 应用服务时,请遵循教程:将现有自定义 SSL 证书绑定到 Azure Web 应用中的指导。
选项
以下突出显示的代码调用 AddHttpsRedirection 来配置中间件选项:
using static Microsoft.AspNetCore.Http.StatusCodes;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.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");
});
builder.Services.AddHttpsRedirection(options =>
{
options.RedirectStatusCode = Status307TemporaryRedirect;
options.HttpsPort = 5001;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
仅在更改 HttpsPort
或 RedirectStatusCode
的值时才需要调用 AddHttpsRedirection
。
上述突出显示的代码:
- 将 HttpsRedirectionOptions.RedirectStatusCode 设置为 Status307TemporaryRedirect,这是默认值。 使用 StatusCodes 类的字段进行
RedirectStatusCode
的分配。 - 将 HTTPS 端口设置为 5001。
在生产环境中配置永久性重定向
中间件默认发送包含所有重定向的 Status307TemporaryRedirect。 如果希望在应用处于非开发环境时发送永久性重定向状态代码,请将中间件选项配置包装在非开发环境的条件检查中。
在 Program.cs
中配置服务时:
using static Microsoft.AspNetCore.Http.StatusCodes;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
if (!builder.Environment.IsDevelopment())
{
builder.Services.AddHttpsRedirection(options =>
{
options.RedirectStatusCode = Status308PermanentRedirect;
options.HttpsPort = 443;
});
}
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
HTTPS 重定向中间件替代方法
使用 HTTPS 重定向中间件 (UseHttpsRedirection
) 的替代方法是使用 URL 重写中间件 (AddRedirectToHttps
)。 AddRedirectToHttps
还可以设置执行重定向时的状态码和端口。 有关详细信息,请参阅 URL 重写中间件。
当重定向到 HTTPS 并且不需要其他重定向规则时,建议使用本文所述的 HTTPS 重定向中间件 (UseHttpsRedirection
)。
HTTP 严格传输安全协议 (HSTS)
根据 OWASP,HTTP 严格传输安全 (HSTS) 是一种可选的安全增强功能,由 Web 应用通过使用响应标头来指定。 当支持 HSTS 的浏览器收到此标头时:
- 该浏览器会存储防止通过 HTTP 发送任何通信的域配置。 该浏览器会强制通过 HTTPS 进行所有通信。
- 该浏览器会阻止用户使用不受信任或无效的证书。 该浏览器会禁用允许用户暂时信任此类证书的提示。
由于客户端强制使用 HSTS,因此它存在一些限制:
- 客户端必须支持 HSTS。
- HSTS 需要至少一个成功的 HTTPS 请求才能建立 HSTS 策略。
- 应用程序必须检查每个 HTTP 请求,并重定向或拒绝 HTTP 请求。
ASP.NET Core 使用 UseHsts 扩展方法实现 HSTS。 当应用未处于开发模式时,以下代码会调用 UseHsts
:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
不建议在开发环境中使用 UseHsts
,因为 HSTS 设置对浏览器而言是高度可缓存的。 默认情况下,UseHsts
不包括本地环回地址。
对于首次实现 HTTPS 的生产环境,使用 TimeSpan 方法之一将初始 HstsOptions.MaxAge 设置为较小的值。 如果需要将 HTTPS 基础结构还原为 HTTP,请将值从几小时设置为不超过一天。 确信 HTTPS 配置可持续后,增加 HSTS max-age
值;常用的值是一年。
以下突出显示的代码:
using static Microsoft.AspNetCore.Http.StatusCodes;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.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");
});
builder.Services.AddHttpsRedirection(options =>
{
options.RedirectStatusCode = Status307TemporaryRedirect;
options.HttpsPort = 5001;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
- 设置
Strict-Transport-Security
标头的预加载参数。 RFC HSTS 规范中不包含预加载,但 Web 浏览器支持在新安装时预加载 HSTS 站点。 有关详细信息,请参阅 https://hstspreload.org/。 - 启用 includeSubDomain,它会将 HSTS 策略应用于主机子域。
- 将
Strict-Transport-Security
标头的max-age
参数显式设置为 60 天。 如果未设置,则默认为 30 天。 有关详细信息,请参阅 max-age 指令。 - 将
example.com
添加到要排除的主机列表中。
UseHsts
不包括以下环回主机:
localhost
:IPv4 环回地址。127.0.0.1
:IPv4 环回地址。[::1]
:IPv6 环回地址。
在项目创建时选择退出 HTTPS/HSTS
在一些后端服务场景中,连接安全性是在网络面向公众的边缘处理的,因此无需在每个节点上配置连接安全性。 从 Visual Studio 中的模板或 dotnet new 命令生成的 Web 应用启用 HTTPS 重定向和 HSTS。 对于不需要这些方案的部署,可以在从模板创建应用时选择退出 HTTPS/HSTS。
若要选择退出 HTTPS/HSTS,请执行以下操作:
取消选中“针对 HTTPS 进行配置”复选框。
信任 ASP.NET Core HTTPS 开发证书
.NET Core SDK 包含 HTTPS 开发证书。 该证书是作为首次运行体验的一部分安装的。 例如,dotnet --info
会生成以下输出的变体:
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 开发证书安装到本地用户证书存储。 该证书已安装,但它不受信任。 要信任该证书,请执行一次性步骤来运行 dotnet dev-certs
工具:
dotnet dev-certs https --trust
下面的命令提供有关 dotnet dev-certs
工具的帮助:
dotnet dev-certs https --help
警告
请勿在将被重新分发的环境中创建开发证书,例如容器映像或虚拟机。 这样做可能会导致欺骗和特权提升。 为了帮助防止出现这种情况,请在第一次调用 .NET CLI 之前,将 DOTNET_GENERATE_ASPNET_CERTIFICATE
环境变量设置为 false
。 这将在 CLI 的首次运行体验期间跳过自动生成 ASP.NET Core 开发证书。
如何为 Docker 设置开发人员证书
请参阅此 GitHub 问题。
特定于 Linux 的注意事项
Linux 发行版在将证书标记为受信任的方式上存在很大差异。 虽然 dotnet dev-certs
预计广泛适用,但它仅在 Ubuntu 和 Fedora 上得到正式支持,专门旨在确保对基于 Firefox 和 Chromium 的浏览器(Edge、Chrome 和 Chromium)的信任。
依赖项
若要建立 OpenSSL 信任,该 openssl
工具必须位于路径上。
若要建立浏览器信任(例如在 Edge 或 Firefox 中),该 certutil
工具必须位于路径上。
OpenSSL 信任
当 ASP.NET Core 开发证书受信任时,该证书将导出到当前用户的 home 目录的文件夹中。 若要让 OpenSSL(和使用它的客户端)选取此文件夹,需要设置 SSL_CERT_DIR
环境变量。 可以在单个会话中执行此操作,方法是运行类似于 export SSL_CERT_DIR=$HOME/.aspnet/dev-certs/trust:/usr/lib/ssl/certs
的命令(传递 --verbose
时,确切值会出现在输出中)或将其添加到(特定于发行版和 shell 的)配置文件(例如 .profile
)。
这是使 curl
等工具信任开发证书所必需的。 或者,也可以将 -CAfile
或 -CApath
传递给每个单独的 curl
调用。
请注意,这需要 1.1.1h 或更高版本或 3.0.0 或更高版本,具体取决于所使用的主版本。
如果 OpenSSL 信任陷入错误状态(例如,dotnet dev-certs https --clean
无法删除它),通常可以使用 c_rehash
工具将其恢复正常。
覆盖
如果使用具有自己的网络安全服务 (NSS) 存储区的其他浏览器,则可以使用 DOTNET_DEV_CERTS_NSSDB_PATHS
环境变量来指定一个以冒号分隔的 NSS 目录(例如,包含 cert9.db
的目录)列表,以便向其添加开发证书。
如果将希望 OpenSSL 信任的证书存储在特定目录中,则可以使用 DOTNET_DEV_CERTS_OPENSSL_CERTIFICATE_DIRECTORY
环境变量来指示其位置。
警告
如果设置其中任一变量,请务必在每次更新信任时将其设置为相同的值。 如果它们更改,工具就无法知道在以前位置上的证书(例如清理证书)。
使用 sudo
与其他平台上一样,开发证书是针对每个用户单独存储和信任的。 因此,如果以不同的用户身份运行 dotnet dev-certs
(例如通过使用 sudo
),信任开发证书的将是那个用户(例如 root
)。
在 Linux 上使用 linux-dev-certs 信任 HTTPS 证书
linux-dev-certs 是一种开源、社区支持的 .NET 全局工具,可快捷地在 Linux 上创建和信任开发人员证书。 该工具不由 Microsoft 进行支持或维护。
以下命令安装该工具并创建受信任的开发人员证书:
dotnet tool update -g linux-dev-certs
dotnet linux-dev-certs install
有关详细信息或要报告问题,请参阅 linux-dev-certs GitHub 存储库。
排查证书问题,例如证书不受信任
如果 ASP.NET Core HTTPS 开发证书已安装且受信任,但仍收到证书不受信任的浏览器警告,则本部分可提供帮助。 ASP.NET Core HTTPS 开发证书由 Kestrel 使用。
若要修复 IIS Express 证书,请参阅此 Stackoverflow 问题。
所有平台 - 证书不受信任
运行以下命令:
dotnet dev-certs https --clean
dotnet dev-certs https --trust
关闭所有打开的浏览器实例。 在应用中打开一个新的浏览器窗口。 证书信任由浏览器缓存。
dotnet dev-certs https --clean 失败
上述命令可解决大多数浏览器信任问题。 如果浏览器仍不信任证书,请按照以下特定于该平台的建议操作。
Docker - 证书不受信任
- 删除 C:\Users{USER}\AppData\Roaming\ASP.NET\Https 文件夹。
- 清理解决方案。 删除 bin 和 obj 文件夹。
- 重启开发工具。 例如,Visual Studio 或 Visual Studio Code。
Windows - 证书不受信任
- 检查证书存储中的证书。 在
Current User > Personal > Certificates
和Current User > Trusted root certification authorities > Certificates
下都应有一个具有ASP.NET Core HTTPS development certificate
易记名称的localhost
证书 - 从个人和受信任的根证书颁发机构中删除所有找到的证书。 请勿删除 IIS Express localhost 证书。
- 运行以下命令:
dotnet dev-certs https --clean
dotnet dev-certs https --trust
关闭所有打开的浏览器实例。 在应用中打开一个新的浏览器窗口。
OS X - 证书不受信任
- 打开“密钥链访问”。
- 选择“系统密钥链”。
- 检查是否存在 localhost 证书。
- 检查其图标上是否包含
+
符号,以表明它对于所有用户而言均受信任。 - 从系统密钥链中删除证书。
- 运行以下命令:
dotnet dev-certs https --clean
dotnet dev-certs https --trust
关闭所有打开的浏览器实例。 在应用中打开一个新的浏览器窗口。
若要排查 Visual Studio 的证书问题,请参阅使用 IIS Express 时出现 HTTPS 错误 (dotnet/AspNetCore #16892)。
Linux 证书不受信任
检查配置为信任的证书是否为 Kestrel 服务器将使用的用户 HTTPS 开发人员证书。
在以下位置检查当前用户默认的 HTTPS 开发人员 Kestrel 证书:
ls -la ~/.dotnet/corefx/cryptography/x509stores/my
HTTPS 开发人员 Kestrel 证书文件是 SHA1 指纹。 当通过 dotnet dev-certs https --clean
删除该文件时,会根据需要使用不同的指纹重新生成。
使用以下命令检查导出证书的指纹是否匹配:
openssl x509 -noout -fingerprint -sha1 -inform pem -in /usr/local/share/ca-certificates/aspnet/https.crt
如果该证书不匹配,则可能是以下情况之一:
- 旧证书。
- 为根用户导出了开发人员证书。 对于这种情况,请导出证书。
可在以下位置检查根用户证书:
ls -la /root/.dotnet/corefx/cryptography/x509stores/my
将 IIS Express SSL 证书与 Visual Studio 一起使用
若要解决 IIS Express 证书的问题,请在 Visual Studio 安装程序中选择“修复”。 有关详细信息,请参阅此 GitHub 问题。
组策略可阻止信任自签名证书
在某些情况下,组策略可能会阻止信任自签名证书。 有关详细信息,请参阅此 GitHub 问题。
其他信息
注意
如果你使用的是 .NET 9 SDK 或更高版本,请参阅本文的 .NET 9 版本中更新的 Linux 操作流程。
警告
API 项目
请勿在接收敏感信息的 Web API 上使用 RequireHttpsAttributeRequireHttpsAttribute。 RequireHttpsAttribute
使用 HTTP 状态代码将浏览器从 HTTP 重定向到 HTTPS。 API 客户端可能不理解或不遵循从 HTTP 到 HTTPS 的重定向。 此类客户端可以通过 HTTP 发送信息。 Web API 应该执行以下操作之一:
- 不侦听 HTTP。
- 关闭状态码为 400(错误请求)的连接并且不处理请求。
若要在 API 中禁用 HTTP 重定向,请设置 ASPNETCORE_URLS
环境变量或使用 --urls
命令行标志。 有关详细信息,请参阅 Andrew Lock 撰写的在 ASP.NET Core 中使用多个环境和为 ASP.NET Core 应用设置 URL 的 8 种方法。
HSTS 和 API 项目
默认 API 项目不包括 HSTS,因为 HSTS 通常是浏览器专用的指令。 其他调用方(例如电话或桌面应用)不遵循该指令。 即使在浏览器中,通过 HTTP 对 API 的单个经过身份验证的调用在不安全的网络中也会有风险。 安全的方法是将 API 项目配置为仅通过 HTTPS 进行侦听和响应。
HTTP 重定向到 HTTPS 会导致 CORS 预检请求出现 ERR_INVALID_REDIRECT
在 CORS 预检请求时,使用由 UseHttpsRedirection 重定向到 HTTPS 的 HTTP 请求终结点失败,错误为 ERR_INVALID_REDIRECT
。
API 项目可以拒绝 HTTP 请求,而不是使用 UseHttpsRedirection
将请求重定向到 HTTPS。
需要 HTTPS
建议生产 ASP.NET Core web 应用使用:
- HTTPS 重定向中间件 (UseHttpsRedirection) 将 HTTP 请求重定向到 HTTPS。
- HSTS 中间件 (UseHsts) 将 HTTP 严格传输安全协议 (HSTS) 标头发送到客户端。
注意
在反向代理配置中部署的应用允许代理来处理连接安全性 (HTTPS)。 如果该代理也处理 HTTPS 重定向,则无需使用 HTTPS 重定向中间件。 如果代理服务器也处理写入 HSTS 标头(例如,IIS 10.0 (1709) 或更高版本中的本机 HSTS 支持),则应用不需要使用 HSTS 中间件。 有关详细信息,请参阅项目创建时选择退出 HTTPS/HSTS。
UseHttpsRedirection
以下代码调用 Program.cs
文件中的 UseHttpsRedirection:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
上述突出显示的代码:
- 使用默认 HttpsRedirectionOptions.RedirectStatusCode (Status307TemporaryRedirect) 。
- 除非被
ASPNETCORE_HTTPS_PORT
环境变量或 IServerAddressesFeature 替代,否则使用默认 HttpsRedirectionOptions.HttpsPort (null)。
建议使用临时重定向,而不使用永久性重定向。 链接缓存会导致开发环境中的行为不稳定。 如果希望在应用处于非开发环境时发送永久性重定向状态代码,请参阅在生产环境中配置永久性重定向部分。 建议使用 HSTS 向客户端发出信号,即应仅将安全资源请求发送到应用(仅在生产环境中)。
端口配置
中间件必须有可用的端口才能将不安全的请求重定向到 HTTPS。 如果没有可用的端口:
- 不会重定向到 HTTPS。
- 中间件记录“无法确定用于重定向的 https 端口”警告。
使用以下任一方法指定 HTTPS 端口:
设置
https_port
主机设置:在主机配置中。
通过设置
ASPNETCORE_HTTPS_PORT
环境变量。通过在
appsettings.json
中添加顶级条目:{ "https_port": 443, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*" }
使用 ASPNETCORE_URLS 环境变量指示使用安全方案的端口。 该环境变量配置服务器。 中间件通过 IServerAddressesFeature 间接发现 HTTPS 端口。 此方法在反向代理部署中不起作用。
ASP.NET Core Web 模板在
Properties/launchsettings.json
中为 Kestrel 和 IIS Express 设置 HTTPS URL。launchsettings.json
仅在本地计算机上使用。为 Kestrel 服务器或 HTTP.sys 服务器的面向公众的边缘部署配置 HTTPS URL 终结点。 该应用仅使用一个 HTTPS 端口。 中间件通过 IServerAddressesFeature 发现该端口。
注意
当应用在反向代理配置中运行时,IServerAddressesFeature 不可用。 使用本部分中所述的其他方法之一设置端口。
Edge 部署
当 Kestrel 或 HTTP.sys 用作面向公众的边缘服务器时,必须将 Kestrel 或 HTTP.sys 配置为对这两者进行侦听:
- 重定向客户端的安全端口(通常在生产环境中为 443,在开发环境中为 5001)。
- 不安全的端口(通常在生产环境中为 80,在开发环境中为 5000)。
客户端必须可以访问不安全的端口,以便应用接收不安全的请求并将客户端重定向到安全端口。
有关详细信息,请参阅 Kestrel终结点配置或 ASP.NET Core 中的 HTTP.sys Web 服务器实现。
部署方案
客户端和服务器之间的任何防火墙还必须打开通信端口供流量使用。
如果在反向代理配置中转发请求,请在调用 HTTPS 重定向中间件之前使用转接头中间件。 转接头中间件使用 X-Forwarded-Proto
标头更新 Request.Scheme
。 使用该中间件,重定向 URI 和其他安全策略可以正常工作。 如果不使用转接头中间件,后端应用可能无法接收到正确的方案并最终进入重定向循环。 常见的最终用户错误消息是发生了太多重定向。
部署到 Azure 应用服务时,请遵循教程:将现有自定义 SSL 证书绑定到 Azure Web 应用中的指导。
选项
以下突出显示的代码调用 AddHttpsRedirection 来配置中间件选项:
using static Microsoft.AspNetCore.Http.StatusCodes;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.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");
});
builder.Services.AddHttpsRedirection(options =>
{
options.RedirectStatusCode = Status307TemporaryRedirect;
options.HttpsPort = 5001;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
仅在更改 HttpsPort
或 RedirectStatusCode
的值时才需要调用 AddHttpsRedirection
。
上述突出显示的代码:
- 将 HttpsRedirectionOptions.RedirectStatusCode 设置为 Status307TemporaryRedirect,这是默认值。 使用 StatusCodes 类的字段进行
RedirectStatusCode
的分配。 - 将 HTTPS 端口设置为 5001。
在生产环境中配置永久性重定向
中间件默认发送包含所有重定向的 Status307TemporaryRedirect。 如果希望在应用处于非开发环境时发送永久性重定向状态代码,请将中间件选项配置包装在非开发环境的条件检查中。
在 Program.cs
中配置服务时:
using static Microsoft.AspNetCore.Http.StatusCodes;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
if (!builder.Environment.IsDevelopment())
{
builder.Services.AddHttpsRedirection(options =>
{
options.RedirectStatusCode = Status308PermanentRedirect;
options.HttpsPort = 443;
});
}
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
HTTPS 重定向中间件替代方法
使用 HTTPS 重定向中间件 (UseHttpsRedirection
) 的替代方法是使用 URL 重写中间件 (AddRedirectToHttps
)。 AddRedirectToHttps
还可以设置执行重定向时的状态码和端口。 有关详细信息,请参阅 URL 重写中间件。
当重定向到 HTTPS 并且不需要其他重定向规则时,建议使用本文所述的 HTTPS 重定向中间件 (UseHttpsRedirection
)。
HTTP 严格传输安全协议 (HSTS)
根据 OWASP,HTTP 严格传输安全 (HSTS) 是一种可选的安全增强功能,由 Web 应用通过使用响应标头来指定。 当支持 HSTS 的浏览器收到此标头时:
- 该浏览器会存储防止通过 HTTP 发送任何通信的域配置。 该浏览器会强制通过 HTTPS 进行所有通信。
- 该浏览器会阻止用户使用不受信任或无效的证书。 该浏览器会禁用允许用户暂时信任此类证书的提示。
由于客户端强制使用 HSTS,因此它存在一些限制:
- 客户端必须支持 HSTS。
- HSTS 需要至少一个成功的 HTTPS 请求才能建立 HSTS 策略。
- 应用程序必须检查每个 HTTP 请求,并重定向或拒绝 HTTP 请求。
ASP.NET Core 使用 UseHsts 扩展方法实现 HSTS。 当应用未处于开发模式时,以下代码会调用 UseHsts
:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
不建议在开发环境中使用 UseHsts
,因为 HSTS 设置对浏览器而言是高度可缓存的。 默认情况下,UseHsts
不包括本地环回地址。
对于首次实现 HTTPS 的生产环境,使用 TimeSpan 方法之一将初始 HstsOptions.MaxAge 设置为较小的值。 如果需要将 HTTPS 基础结构还原为 HTTP,请将值从几小时设置为不超过一天。 确信 HTTPS 配置可持续后,增加 HSTS max-age
值;常用的值是一年。
以下突出显示的代码:
using static Microsoft.AspNetCore.Http.StatusCodes;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.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");
});
builder.Services.AddHttpsRedirection(options =>
{
options.RedirectStatusCode = Status307TemporaryRedirect;
options.HttpsPort = 5001;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
- 设置
Strict-Transport-Security
标头的预加载参数。 RFC HSTS 规范中不包含预加载,但 Web 浏览器支持在新安装时预加载 HSTS 站点。 有关详细信息,请参阅 https://hstspreload.org/。 - 启用 includeSubDomain,它会将 HSTS 策略应用于主机子域。
- 将
Strict-Transport-Security
标头的max-age
参数显式设置为 60 天。 如果未设置,则默认为 30 天。 有关详细信息,请参阅 max-age 指令。 - 将
example.com
添加到要排除的主机列表中。
UseHsts
不包括以下环回主机:
localhost
:IPv4 环回地址。127.0.0.1
:IPv4 环回地址。[::1]
:IPv6 环回地址。
在项目创建时选择退出 HTTPS/HSTS
在一些后端服务场景中,连接安全性是在网络面向公众的边缘处理的,因此无需在每个节点上配置连接安全性。 从 Visual Studio 中的模板或 dotnet new 命令生成的 Web 应用启用 HTTPS 重定向和 HSTS。 对于不需要这些方案的部署,可以在从模板创建应用时选择退出 HTTPS/HSTS。
若要选择退出 HTTPS/HSTS,请执行以下操作:
取消选中“针对 HTTPS 进行配置”复选框。
信任 Windows 和 macOS 上的 ASP.NET Core HTTPS 开发证书
对于 Firefox 浏览器,请参阅下一部分。
.NET Core SDK 包含 HTTPS 开发证书。 该证书是作为首次运行体验的一部分安装的。 例如,dotnet --info
会生成以下输出的变体:
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 开发证书安装到本地用户证书存储。 该证书已安装,但它不受信任。 要信任该证书,请执行一次性步骤来运行 dotnet dev-certs
工具:
dotnet dev-certs https --trust
下面的命令提供有关 dotnet dev-certs
工具的帮助:
dotnet dev-certs https --help
警告
请勿在将被重新分发的环境中创建开发证书,例如容器映像或虚拟机。 这样做可能会导致欺骗和特权提升。 为了帮助防止出现这种情况,请在第一次调用 .NET CLI 之前,将 DOTNET_GENERATE_ASPNET_CERTIFICATE
环境变量设置为 false
。 这将在 CLI 的首次运行体验期间跳过自动生成 ASP.NET Core 开发证书。
使用 Firefox 信任 HTTPS 证书以防止出现 SEC_ERROR_INADEQUATE_KEY_USAGE 错误
Firefox 浏览器使用自己的证书存储,因此不信任 IIS Express 或 Kestrel 开发人员证书。
使用 Firefox 信任 HTTPS 证书有两种方法:创建策略文件或使用 FireFox 浏览器进行配置。 配置该浏览器会创建策略文件,因此这两种方法是等效的。
创建策略文件以使用 Firefox 信任 HTTPS 证书
在以下位置复制策略文件 (policies.json
):
- Windows:
%PROGRAMFILES%\Mozilla Firefox\distribution\
- MacOS:
Firefox.app/Contents/Resources/distribution
- Linux:请参阅本文中的在 Linux 上使用 Firefox 信任证书。
将以下 JSON 添加到 Firefox 策略文件:
{
"policies": {
"Certificates": {
"ImportEnterpriseRoots": true
}
}
}
前面的策略文件使 Firefox 信任证书,这些证书来自 Windows 证书存储中的受信任证书。 下一部分提供了另一种方法来使用 Firefox 浏览器创建上述策略文件。
使用 Firefox 浏览器配置 HTTPS 证书信任
使用以下说明设置 security.enterprise_roots.enabled
= true
:
- 在 FireFox 浏览器中输入
about:config
。 - 如果你接受风险,请选择“接受风险并继续”。
- 选择“全部显示”
- 设置
security.enterprise_roots.enabled
=true
- 退出并重启 Firefox
有关详细信息,请参阅在 Firefox 中设置证书颁发机构 (CA) 和 mozilla/policy-templates/README 文件。
如何为 Docker 设置开发人员证书
请参阅此 GitHub 问题。
在 Linux 上信任 HTTPS 证书
建立信任是特定于发行版和浏览器的。 以下部分提供了针对一些常用发行版和 Chromium 浏览器(Edge 和 Chrome)以及针对 Firefox 的说明。
Ubuntu 信任用于进行服务到服务通信的证书
以下说明不适用于某些 Ubuntu 版本,例如 20.04。 有关详细信息,请参阅 GitHub 问题 dotnet/AspNetCore.Docs #23686。
安装 OpenSSL 1.1.1h 或更高版本。 有关如何更新 OpenSSL 的说明,请参阅你的发行版。
运行以下命令:
dotnet dev-certs https sudo -E dotnet dev-certs https -ep /usr/local/share/ca-certificates/aspnet/https.crt --format PEM sudo update-ca-certificates
前面的命令:
- 确保创建了当前用户的开发人员证书。
- 使用当前用户的环境导出具有
ca-certificates
文件夹所需的提升权限的证书。 - 删除
-E
标志会导出根用户证书,并根据需要生成它。 每个新生成的证书都有不同的指纹。 以根用户身份运行时,不需要sudo
和-E
。
上述命令中的路径特定于 Ubuntu。 对于其他发行版,请选择相应的路径或使用证书颁发机构 (CA) 的路径。
在 Linux 上使用 Edge 或 Chrome 信任 HTTPS 证书
对于 Linux 上的 chromium 浏览器:
为你的发行版安装
libnss3-tools
。创建
$HOME/.pki/nssdb
文件夹或验证计算机上是否存在该文件夹。使用以下命令导出证书:
dotnet dev-certs https sudo -E dotnet dev-certs https -ep /usr/local/share/ca-certificates/aspnet/https.crt --format PEM
上述命令中的路径特定于 Ubuntu。 对于其他发行版,请选择相应的路径或使用证书颁发机构 (CA) 的路径。
运行以下命令:
certutil -d sql:$HOME/.pki/nssdb -A -t "P,," -n localhost -i /usr/local/share/ca-certificates/aspnet/https.crt
退出并重启浏览器。
在 Linux 上使用 Firefox 信任证书
使用以下命令导出证书:
dotnet dev-certs https sudo -E dotnet dev-certs https -ep /usr/local/share/ca-certificates/aspnet/https.crt --format PEM
上述命令中的路径特定于 Ubuntu。 对于其他发行版,请选择相应的路径或使用证书颁发机构 (CA) 的路径。
使用以下命令在
/usr/lib/firefox/distribution/policies.json
创建 JSON 文件:
cat <<EOF | sudo tee /usr/lib/firefox/distribution/policies.json
{
"policies": {
"Certificates": {
"Install": [
"/usr/local/share/ca-certificates/aspnet/https.crt"
]
}
}
}
EOF
注意:Ubuntu 21.10 Firefox 作为快照包提供,安装文件夹为 /snap/firefox/current/usr/lib/firefox
。
有关使用浏览器配置策略文件的替代方法,请参阅本文中的使用 Firefox 浏览器配置 HTTPS 证书信任。
使用 Fedora 34 信任证书
请参阅:
- 此 GitHub 注释
- Fedora:使用共享系统证书
- 在 Fedora 上设置 .NET 开发环境。
使用其他发行版信任证书
请参阅此 GitHub 问题。
信任来自适用于 Linux 的 Windows 子系统的 HTTPS 证书
以下说明不适用于某些 Linux 发行版,例如 Ubuntu 20.04。 有关详细信息,请参阅 GitHub 问题 dotnet/AspNetCore.Docs #23686。
适用于 Linux 的 Windows 子系统 (WSL) 生成 HTTPS 自签名开发证书,默认情况下,该证书在 Windows 中不受信任。 让 Windows 信任 WSL 证书的最简单方法是将 WSL 配置为使用与 Windows 相同的证书:
在 Windows 上,将开发者证书导出到文件:
dotnet dev-certs https -ep https.pfx -p $CREDENTIAL_PLACEHOLDER$ --trust
其中
$CREDENTIAL_PLACEHOLDER$
是密码。在 WSL 窗口中,将导出的证书导入 WSL 实例:
dotnet dev-certs https --clean --import <<path-to-pfx>> --password $CREDENTIAL_PLACEHOLDER$
上述方法是按每个证书和每个 WSL 发行版进行的一次性操作。 这比反复导出证书更容易。 如果在 Windows 上更新或重新生成证书,则可能需要再次运行上述命令。
排查证书问题,例如证书不受信任
如果 ASP.NET Core HTTPS 开发证书已安装且受信任,但仍收到证书不受信任的浏览器警告,则本部分可提供帮助。 ASP.NET Core HTTPS 开发证书由 Kestrel 使用。
若要修复 IIS Express 证书,请参阅此 Stackoverflow 问题。
所有平台 - 证书不受信任
运行以下命令:
dotnet dev-certs https --clean
dotnet dev-certs https --trust
关闭所有打开的浏览器实例。 在应用中打开一个新的浏览器窗口。 证书信任由浏览器缓存。
dotnet dev-certs https --clean 失败
上述命令可解决大多数浏览器信任问题。 如果浏览器仍不信任证书,请按照以下特定于该平台的建议操作。
Docker - 证书不受信任
- 删除 C:\Users{USER}\AppData\Roaming\ASP.NET\Https 文件夹。
- 清理解决方案。 删除 bin 和 obj 文件夹。
- 重启开发工具。 例如,Visual Studio 或 Visual Studio Code。
Windows - 证书不受信任
- 检查证书存储中的证书。 在
Current User > Personal > Certificates
和Current User > Trusted root certification authorities > Certificates
下都应有一个具有ASP.NET Core HTTPS development certificate
易记名称的localhost
证书 - 从个人和受信任的根证书颁发机构中删除所有找到的证书。 请勿删除 IIS Express localhost 证书。
- 运行以下命令:
dotnet dev-certs https --clean
dotnet dev-certs https --trust
关闭所有打开的浏览器实例。 在应用中打开一个新的浏览器窗口。
OS X - 证书不受信任
- 打开“密钥链访问”。
- 选择“系统密钥链”。
- 检查是否存在 localhost 证书。
- 检查其图标上是否包含
+
符号,以表明它对于所有用户而言均受信任。 - 从系统密钥链中删除证书。
- 运行以下命令:
dotnet dev-certs https --clean
dotnet dev-certs https --trust
关闭所有打开的浏览器实例。 在应用中打开一个新的浏览器窗口。
若要排查 Visual Studio 的证书问题,请参阅使用 IIS Express 时出现 HTTPS 错误 (dotnet/AspNetCore #16892)。
Linux 证书不受信任
检查配置为信任的证书是否为 Kestrel 服务器将使用的用户 HTTPS 开发人员证书。
在以下位置检查当前用户默认的 HTTPS 开发人员 Kestrel 证书:
ls -la ~/.dotnet/corefx/cryptography/x509stores/my
HTTPS 开发人员 Kestrel 证书文件是 SHA1 指纹。 当通过 dotnet dev-certs https --clean
删除该文件时,会根据需要使用不同的指纹重新生成。
使用以下命令检查导出证书的指纹是否匹配:
openssl x509 -noout -fingerprint -sha1 -inform pem -in /usr/local/share/ca-certificates/aspnet/https.crt
如果该证书不匹配,则可能是以下情况之一:
- 旧证书。
- 为根用户导出了开发人员证书。 对于这种情况,请导出证书。
可在以下位置检查根用户证书:
ls -la /root/.dotnet/corefx/cryptography/x509stores/my
将 IIS Express SSL 证书与 Visual Studio 一起使用
若要解决 IIS Express 证书的问题,请在 Visual Studio 安装程序中选择“修复”。 有关详细信息,请参阅此 GitHub 问题。
组策略可阻止信任自签名证书
在某些情况下,组策略可能会阻止信任自签名证书。 有关详细信息,请参阅此 GitHub 问题。
其他信息
警告
API 项目
请勿在接收敏感信息的 Web API 上使用 RequireHttpsAttributeRequireHttpsAttribute。 RequireHttpsAttribute
使用 HTTP 状态代码将浏览器从 HTTP 重定向到 HTTPS。 API 客户端可能不理解或不遵循从 HTTP 到 HTTPS 的重定向。 此类客户端可以通过 HTTP 发送信息。 Web API 应该执行以下操作之一:
- 不侦听 HTTP。
- 关闭状态码为 400(错误请求)的连接并且不处理请求。
若要在 API 中禁用 HTTP 重定向,请设置 ASPNETCORE_URLS
环境变量或使用 --urls
命令行标志。 有关详细信息,请参阅 Andrew Lock 撰写的在 ASP.NET Core 中使用多个环境和为 ASP.NET Core 应用设置 URL 的 5 种方法。
HSTS 和 API 项目
默认 API 项目不包括 HSTS,因为 HSTS 通常是浏览器专用的指令。 其他调用方(例如电话或桌面应用)不遵循该指令。 即使在浏览器中,通过 HTTP 对 API 的单个经过身份验证的调用在不安全的网络中也会有风险。 安全的方法是将 API 项目配置为仅通过 HTTPS 进行侦听和响应。
需要 HTTPS
建议生产 ASP.NET Core web 应用使用:
- HTTPS 重定向中间件 (UseHttpsRedirection) 将 HTTP 请求重定向到 HTTPS。
- HSTS 中间件 (UseHsts) 将 HTTP 严格传输安全协议 (HSTS) 标头发送到客户端。
注意
在反向代理配置中部署的应用允许代理来处理连接安全性 (HTTPS)。 如果该代理也处理 HTTPS 重定向,则无需使用 HTTPS 重定向中间件。 如果代理服务器也处理写入 HSTS 标头(例如,IIS 10.0 (1709) 或更高版本中的本机 HSTS 支持),则应用不需要使用 HSTS 中间件。 有关详细信息,请参阅项目创建时选择退出 HTTPS/HSTS。
UseHttpsRedirection
以下代码调用 Startup
类中的 UseHttpsRedirection
:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
上述突出显示的代码:
- 使用默认 HttpsRedirectionOptions.RedirectStatusCode (Status307TemporaryRedirect) 。
- 除非被
ASPNETCORE_HTTPS_PORT
环境变量或 IServerAddressesFeature 替代,否则使用默认 HttpsRedirectionOptions.HttpsPort (null)。
建议使用临时重定向,而不使用永久性重定向。 链接缓存会导致开发环境中的行为不稳定。 如果希望在应用处于非开发环境时发送永久性重定向状态代码,请参阅在生产环境中配置永久性重定向部分。 建议使用 HSTS 向客户端发出信号,即应仅将安全资源请求发送到应用(仅在生产环境中)。
端口配置
中间件必须有可用的端口才能将不安全的请求重定向到 HTTPS。 如果没有可用的端口:
- 不会重定向到 HTTPS。
- 中间件记录“无法确定用于重定向的 https 端口”警告。
使用以下任一方法指定 HTTPS 端口:
设置
https_port
主机设置:在主机配置中。
通过设置
ASPNETCORE_HTTPS_PORT
环境变量。通过在
appsettings.json
中添加顶级条目:{ "https_port": 443, "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "AllowedHosts": "*" }
使用 ASPNETCORE_URLS 环境变量指示使用安全方案的端口。 该环境变量配置服务器。 中间件通过 IServerAddressesFeature 间接发现 HTTPS 端口。 此方法在反向代理部署中不起作用。
在开发环境中,在
launchsettings.json
中设置 HTTPS URL。 使用 IIS Express 时启用 HTTPS。为 Kestrel 服务器或 HTTP.sys 服务器的面向公众的边缘部署配置 HTTPS URL 终结点。 该应用仅使用一个 HTTPS 端口。 中间件通过 IServerAddressesFeature 发现该端口。
注意
当应用在反向代理配置中运行时,IServerAddressesFeature 不可用。 使用本部分中所述的其他方法之一设置端口。
Edge 部署
当 Kestrel 或 HTTP.sys 用作面向公众的边缘服务器时,必须将 Kestrel 或 HTTP.sys 配置为对这两者进行侦听:
- 重定向客户端的安全端口(通常在生产环境中为 443,在开发环境中为 5001)。
- 不安全的端口(通常在生产环境中为 80,在开发环境中为 5000)。
客户端必须可以访问不安全的端口,以便应用接收不安全的请求并将客户端重定向到安全端口。
有关详细信息,请参阅 Kestrel终结点配置或 ASP.NET Core 中的 HTTP.sys Web 服务器实现。
部署方案
客户端和服务器之间的任何防火墙还必须打开通信端口供流量使用。
如果在反向代理配置中转发请求,请在调用 HTTPS 重定向中间件之前使用转接头中间件。 转接头中间件使用 X-Forwarded-Proto
标头更新 Request.Scheme
。 使用该中间件,重定向 URI 和其他安全策略可以正常工作。 如果不使用转接头中间件,后端应用可能无法接收到正确的方案并最终进入重定向循环。 常见的最终用户错误消息是发生了太多重定向。
部署到 Azure 应用服务时,请遵循教程:将现有自定义 SSL 证书绑定到 Azure Web 应用中的指导。
选项
以下突出显示的代码调用 AddHttpsRedirection 来配置中间件选项:
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
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 = (int) HttpStatusCode.TemporaryRedirect;
options.HttpsPort = 5001;
});
}
仅在更改 HttpsPort
或 RedirectStatusCode
的值时才需要调用 AddHttpsRedirection
。
上述突出显示的代码:
- 将 HttpsRedirectionOptions.RedirectStatusCode 设置为 Status307TemporaryRedirect,这是默认值。 使用 StatusCodes 类的字段进行
RedirectStatusCode
的分配。 - 将 HTTPS 端口设置为 5001。
在生产环境中配置永久性重定向
中间件默认发送包含所有重定向的 Status307TemporaryRedirect。 如果希望在应用处于非开发环境时发送永久性重定向状态代码,请将中间件选项配置包装在非开发环境的条件检查中。
在 Startup.cs
中配置服务时:
public void ConfigureServices(IServiceCollection services)
{
// IWebHostEnvironment (stored in _env) is injected into the Startup class.
if (!_env.IsDevelopment())
{
services.AddHttpsRedirection(options =>
{
options.RedirectStatusCode = (int) HttpStatusCode.PermanentRedirect;
options.HttpsPort = 443;
});
}
}
HTTPS 重定向中间件替代方法
使用 HTTPS 重定向中间件 (UseHttpsRedirection
) 的替代方法是使用 URL 重写中间件 (AddRedirectToHttps
)。 AddRedirectToHttps
还可以设置执行重定向时的状态码和端口。 有关详细信息,请参阅 URL 重写中间件。
当重定向到 HTTPS 并且不需要其他重定向规则时,建议使用本文所述的 HTTPS 重定向中间件 (UseHttpsRedirection
)。
HTTP 严格传输安全协议 (HSTS)
根据 OWASP,HTTP 严格传输安全 (HSTS) 是一种可选的安全增强功能,由 Web 应用通过使用响应标头来指定。 当支持 HSTS 的浏览器收到此标头时:
- 该浏览器会存储防止通过 HTTP 发送任何通信的域配置。 该浏览器会强制通过 HTTPS 进行所有通信。
- 该浏览器会阻止用户使用不受信任或无效的证书。 该浏览器会禁用允许用户暂时信任此类证书的提示。
由于客户端强制使用 HSTS,因此它存在一些限制:
- 客户端必须支持 HSTS。
- HSTS 需要至少一个成功的 HTTPS 请求才能建立 HSTS 策略。
- 应用程序必须检查每个 HTTP 请求,并重定向或拒绝 HTTP 请求。
ASP.NET Core 使用 UseHsts
扩展方法实现 HSTS。 当应用未处于开发模式时,以下代码会调用 UseHsts
:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
不建议在开发环境中使用 UseHsts
,因为 HSTS 设置对浏览器而言是高度可缓存的。 默认情况下,UseHsts
不包括本地环回地址。
对于首次实现 HTTPS 的生产环境,使用 TimeSpan 方法之一将初始 HstsOptions.MaxAge 设置为较小的值。 如果需要将 HTTPS 基础结构还原为 HTTP,请将值从几小时设置为不超过一天。 确信 HTTPS 配置可持续后,增加 HSTS max-age
值;常用的值是一年。
下面的代码:
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
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 = (int) HttpStatusCode.TemporaryRedirect;
options.HttpsPort = 5001;
});
}
- 设置
Strict-Transport-Security
标头的预加载参数。 RFC HSTS 规范中不包含预加载,但 Web 浏览器支持在新安装时预加载 HSTS 站点。 有关详细信息,请参阅 https://hstspreload.org/。 - 启用 includeSubDomain,它会将 HSTS 策略应用于主机子域。
- 将
Strict-Transport-Security
标头的max-age
参数显式设置为 60 天。 如果未设置,则默认为 30 天。 有关详细信息,请参阅 max-age 指令。 - 将
example.com
添加到要排除的主机列表中。
UseHsts
不包括以下环回主机:
localhost
:IPv4 环回地址。127.0.0.1
:IPv4 环回地址。[::1]
:IPv6 环回地址。
在项目创建时选择退出 HTTPS/HSTS
在一些后端服务场景中,连接安全性是在网络面向公众的边缘处理的,因此无需在每个节点上配置连接安全性。 从 Visual Studio 中的模板或 dotnet new 命令生成的 Web 应用启用 HTTPS 重定向和 HSTS。 对于不需要这些方案的部署,可以在从模板创建应用时选择退出 HTTPS/HSTS。
若要选择退出 HTTPS/HSTS,请执行以下操作:
取消选中“针对 HTTPS 进行配置”复选框。
信任 Windows 和 macOS 上的 ASP.NET Core HTTPS 开发证书
对于 Firefox 浏览器,请参阅下一部分。
.NET Core SDK 包含 HTTPS 开发证书。 该证书是作为首次运行体验的一部分安装的。 例如,首次运行 dotnet new webapp
会生成以下输出的变体:
Installed an ASP.NET Core HTTPS development certificate.
To trust the certificate, run 'dotnet dev-certs https --trust'
Learn about HTTPS: https://aka.ms/dotnet-https
安装 .NET Core SDK 会将 ASP.NET Core HTTPS 开发证书安装到本地用户证书存储。 该证书已安装,但它不受信任。 要信任该证书,请执行一次性步骤来运行 dotnet dev-certs
工具:
dotnet dev-certs https --trust
下面的命令提供有关 dotnet dev-certs
工具的帮助:
dotnet dev-certs https --help
警告
请勿在将被重新分发的环境中创建开发证书,例如容器映像或虚拟机。 这样做可能会导致欺骗和特权提升。 为了帮助防止出现这种情况,请在第一次调用 .NET CLI 之前,将 DOTNET_GENERATE_ASPNET_CERTIFICATE
环境变量设置为 false
。 这将在 CLI 的首次运行体验期间跳过自动生成 ASP.NET Core 开发证书。
使用 Firefox 信任 HTTPS 证书以防止出现 SEC_ERROR_INADEQUATE_KEY_USAGE 错误
Firefox 浏览器使用自己的证书存储,因此不信任 IIS Express 或 Kestrel 开发人员证书。
使用 Firefox 信任 HTTPS 证书有两种方法:创建策略文件或使用 FireFox 浏览器进行配置。 配置该浏览器会创建策略文件,因此这两种方法是等效的。
创建策略文件以使用 Firefox 信任 HTTPS 证书
在以下位置复制策略文件 (policies.json
):
- Windows:
%PROGRAMFILES%\Mozilla Firefox\distribution\
- MacOS:
Firefox.app/Contents/Resources/distribution
- Linux:请参阅本文后面的在 Linux 上使用 Firefox 信任证书。
将以下 JSON 添加到 Firefox 策略文件:
{
"policies": {
"Certificates": {
"ImportEnterpriseRoots": true
}
}
}
前面的策略文件使 Firefox 信任证书,这些证书来自 Windows 证书存储中的受信任证书。 下一部分提供了另一种方法来使用 Firefox 浏览器创建上述策略文件。
使用 Firefox 浏览器配置 HTTPS 证书信任
使用以下说明设置 security.enterprise_roots.enabled
= true
:
- 在 FireFox 浏览器中输入
about:config
。 - 如果你接受风险,请选择“接受风险并继续”。
- 选择“全部显示”。
- 设置
security.enterprise_roots.enabled
=true
。 - 退出并重启 Firefox。
有关详细信息,请参阅在 Firefox 中设置证书颁发机构 (CA) 和 mozilla/policy-templates/README 文件。
如何为 Docker 设置开发人员证书
请参阅此 GitHub 问题。
在 Linux 上信任 HTTPS 证书
建立信任是特定于发行版和浏览器的。 以下部分提供了针对一些常用发行版和 Chromium 浏览器(Edge 和 Chrome)以及针对 Firefox 的说明。
Ubuntu 信任用于进行服务到服务通信的证书
安装 OpenSSL 1.1.1h 或更高版本。 有关如何更新 OpenSSL 的说明,请参阅你的发行版。
运行以下命令:
dotnet dev-certs https sudo -E dotnet dev-certs https -ep /usr/local/share/ca-certificates/aspnet/https.crt --format PEM sudo update-ca-certificates
前面的命令:
- 确保创建了当前用户的开发人员证书。
- 使用当前用户的环境导出具有
ca-certificates
文件夹所需提升权限的证书。 - 移除
-E
标志会导出根用户证书,并根据需要生成它。 每个新生成的证书都有不同的指纹。 以根用户身份运行时,不需要sudo
和-E
。
上述命令中的路径特定于 Ubuntu。 对于其他发行版,请选择相应的路径或使用证书颁发机构 (CA) 的路径。
在 Linux 上使用 Edge 或 Chrome 信任 HTTPS 证书
对于 Linux 上的 chromium 浏览器:
为你的发行版安装
libnss3-tools
。创建
$HOME/.pki/nssdb
文件夹或验证计算机上是否存在该文件夹。使用以下命令导出证书:
dotnet dev-certs https sudo -E dotnet dev-certs https -ep /usr/local/share/ca-certificates/aspnet/https.crt --format PEM
上述命令中的路径特定于 Ubuntu。 对于其他发行版,请选择相应的路径或使用证书颁发机构 (CA) 的路径。
运行以下命令:
certutil -d sql:$HOME/.pki/nssdb -A -t "P,," -n localhost -i /usr/local/share/ca-certificates/aspnet/https.crt
退出并重启浏览器。
在 Linux 上使用 Firefox 信任证书
使用以下命令导出证书:
dotnet dev-certs https sudo -E dotnet dev-certs https -ep /usr/local/share/ca-certificates/aspnet/https.crt --format PEM
上述命令中的路径特定于 Ubuntu。 对于其他发行版,请选择相应的路径或使用证书颁发机构 (CA) 的路径。
在
/usr/lib/firefox/distribution/policies.json
中创建一个 JSON 文件,其中包含以下内容:
cat <<EOF | sudo tee /usr/lib/firefox/distribution/policies.json
{
"policies": {
"Certificates": {
"Install": [
"/usr/local/share/ca-certificates/aspnet/https.crt"
]
}
}
}
EOF
有关使用浏览器配置策略文件的替代方法,请参阅本文中的使用 Firefox 浏览器配置 HTTPS 证书信任。
使用 Fedora 34 信任证书
Fedora 上的 Firefox
echo 'pref("general.config.filename", "firefox.cfg");
pref("general.config.obscure_value", 0);' > ./autoconfig.js
echo '//Enable policies.json
lockPref("browser.policies.perUserDir", false);' > firefox.cfg
echo "{
\"policies\": {
\"Certificates\": {
\"Install\": [
\"aspnetcore-localhost-https.crt\"
]
}
}
}" > policies.json
dotnet dev-certs https -ep localhost.crt --format PEM
sudo mv autoconfig.js /usr/lib64/firefox/
sudo mv firefox.cfg /usr/lib64/firefox/
sudo mv policies.json /usr/lib64/firefox/distribution/
mkdir -p ~/.mozilla/certificates
cp localhost.crt ~/.mozilla/certificates/aspnetcore-localhost-https.crt
rm localhost.crt
在 Fedora 上信任 dotnet-to-dotnet
sudo cp localhost.crt /etc/pki/tls/certs/localhost.pem
sudo update-ca-trust
rm localhost.crt
有关详细信息,请参阅此 GitHub 注释。
使用其他发行版信任证书
请参阅此 GitHub 问题。
信任来自适用于 Linux 的 Windows 子系统的 HTTPS 证书
适用于 Linux 的 Windows 子系统 (WSL) 会生成 HTTPS 自签名开发证书。 若要将 Windows 证书存储配置为信任 WSL 证书,请执行以下操作:
将开发人员证书导出到 Windows 上的文件:
dotnet dev-certs https -ep C:\<<path-to-folder>>\aspnetcore.pfx -p $CREDENTIAL_PLACEHOLDER$
其中
$CREDENTIAL_PLACEHOLDER$
是密码。在 WSL 窗口中,将导出的证书导入 WSL 实例:
dotnet dev-certs https --clean --import /mnt/c/<<path-to-folder>>/aspnetcore.pfx -p $CREDENTIAL_PLACEHOLDER$
上述方法是按每个证书和每个 WSL 发行版进行的一次性操作。 这比反复导出证书更容易。 如果在 Windows 上更新或重新生成证书,则可能需要再次运行上述命令。
排查证书问题,例如证书不受信任
如果 ASP.NET Core HTTPS 开发证书已安装且受信任,但仍收到证书不受信任的浏览器警告,则本部分可提供帮助。 ASP.NET Core HTTPS 开发证书由 Kestrel 使用。
若要修复 IIS Express 证书,请参阅此 Stackoverflow 问题。
所有平台 - 证书不受信任
运行以下命令:
dotnet dev-certs https --clean
dotnet dev-certs https --trust
关闭打开的任何浏览器实例。 打开应用的新浏览器窗口。 证书信任由浏览器缓存。
dotnet dev-certs https --clean 失败
上述命令可解决大多数浏览器信任问题。 如果浏览器仍不信任证书,请按照以下特定于该平台的建议操作。
Docker - 证书不受信任
- 删除 C:\Users{USER}\AppData\Roaming\ASP.NET\Https 文件夹。
- 清理解决方案。 删除 bin 和 obj 文件夹。
- 重启开发工具。 例如,Visual Studio、Visual Studio Code 或 Visual Studio for Mac。
Windows - 证书不受信任
- 检查证书存储中的证书。 在
Current User > Personal > Certificates
和Current User > Trusted root certification authorities > Certificates
下都应有一个具有ASP.NET Core HTTPS development certificate
易记名称的localhost
证书 - 从个人和受信任的根证书颁发机构中删除所有找到的证书。 请勿删除 IIS Express localhost 证书。
- 运行以下命令:
dotnet dev-certs https --clean
dotnet dev-certs https --trust
关闭打开的任何浏览器实例。 打开应用的新浏览器窗口。 证书信任由浏览器缓存。
OS X - 证书不受信任
- 打开“密钥链访问”。
- 选择“系统密钥链”。
- 检查是否存在 localhost 证书。
- 检查其图标上是否包含
+
符号,以表明它对于所有用户而言均受信任。 - 从系统密钥链中删除证书。
- 运行以下命令:
dotnet dev-certs https --clean
dotnet dev-certs https --trust
关闭打开的任何浏览器实例。 打开应用的新浏览器窗口。 证书信任由浏览器缓存。
若要排查 Visual Studio 的证书问题,请参阅使用 IIS Express 时出现 HTTPS 错误 (dotnet/AspNetCore #16892)。
Linux 证书不受信任
检查配置为信任的证书是否为 Kestrel 服务器将使用的用户 HTTPS 开发人员证书。
在以下位置检查当前用户默认的 HTTPS 开发人员 Kestrel 证书:
ls -la ~/.dotnet/corefx/cryptography/x509stores/my
HTTPS 开发人员 Kestrel 证书文件是 SHA1 指纹。 当通过 dotnet dev-certs https --clean
删除该文件时,会根据需要使用不同的指纹重新生成。
使用以下命令检查导出证书的指纹是否匹配:
openssl x509 -noout -fingerprint -sha1 -inform pem -in /usr/local/share/ca-certificates/aspnet/https.crt
如果该证书不匹配,则可能是以下情况之一:
- 旧证书。
- 为根用户导出了开发人员证书。 对于这种情况,请导出证书。
可在以下位置检查根用户证书:
ls -la /root/.dotnet/corefx/cryptography/x509stores/my
将 IIS Express SSL 证书与 Visual Studio 一起使用
若要解决 IIS Express 证书的问题,请在 Visual Studio 安装程序中选择“修复”。 有关详细信息,请参阅此 GitHub 问题。
其他信息
注意
如果你使用的是 .NET 9 SDK 或更高版本,请参阅本文的 .NET 9 版本中更新的 Linux 操作流程。
警告
API 项目
请勿在接收敏感信息的 Web API 上使用 RequireHttpsAttributeRequireHttpsAttribute。 RequireHttpsAttribute
使用 HTTP 状态代码将浏览器从 HTTP 重定向到 HTTPS。 API 客户端可能不理解或不遵循从 HTTP 到 HTTPS 的重定向。 此类客户端可以通过 HTTP 发送信息。 Web API 应该执行以下操作之一:
- 不侦听 HTTP。
- 关闭状态码为 400(错误请求)的连接并且不处理请求。
若要在 API 中禁用 HTTP 重定向,请设置 ASPNETCORE_URLS
环境变量或使用 --urls
命令行标志。 有关详细信息,请参阅 Andrew Lock 撰写的在 ASP.NET Core 中使用多个环境和为 ASP.NET Core 应用设置 URL 的 8 种方法。
HSTS 和 API 项目
默认 API 项目不包括 HSTS,因为 HSTS 通常是浏览器专用的指令。 其他调用方(例如电话或桌面应用)不遵循该指令。 即使在浏览器中,通过 HTTP 对 API 的单个经过身份验证的调用在不安全的网络中也会有风险。 安全的方法是将 API 项目配置为仅通过 HTTPS 进行侦听和响应。
HTTP 重定向到 HTTPS 会导致 CORS 预检请求出现 ERR_INVALID_REDIRECT
在 CORS 预检请求时,使用由 UseHttpsRedirection 重定向到 HTTPS 的 HTTP 请求终结点失败,错误为 ERR_INVALID_REDIRECT
。
API 项目可以拒绝 HTTP 请求,而不是使用 UseHttpsRedirection
将请求重定向到 HTTPS。
需要 HTTPS
建议生产 ASP.NET Core web 应用使用:
- HTTPS 重定向中间件 (UseHttpsRedirection) 将 HTTP 请求重定向到 HTTPS。
- HSTS 中间件 (UseHsts) 将 HTTP 严格传输安全协议 (HSTS) 标头发送到客户端。
注意
在反向代理配置中部署的应用允许代理来处理连接安全性 (HTTPS)。 如果该代理也处理 HTTPS 重定向,则无需使用 HTTPS 重定向中间件。 如果代理服务器也处理写入 HSTS 标头(例如,IIS 10.0 (1709) 或更高版本中的本机 HSTS 支持),则应用不需要使用 HSTS 中间件。 有关详细信息,请参阅项目创建时选择退出 HTTPS/HSTS。
UseHttpsRedirection
以下代码调用 Program.cs
文件中的 UseHttpsRedirection:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
上述突出显示的代码:
- 使用默认 HttpsRedirectionOptions.RedirectStatusCode (Status307TemporaryRedirect) 。
- 除非被
ASPNETCORE_HTTPS_PORT
环境变量或 IServerAddressesFeature 替代,否则使用默认 HttpsRedirectionOptions.HttpsPort (null)。
建议使用临时重定向,而不使用永久性重定向。 链接缓存会导致开发环境中的行为不稳定。 如果希望在应用处于非开发环境时发送永久性重定向状态代码,请参阅在生产环境中配置永久性重定向部分。 建议使用 HSTS 向客户端发出信号,即应仅将安全资源请求发送到应用(仅在生产环境中)。
端口配置
中间件必须有可用的端口才能将不安全的请求重定向到 HTTPS。 如果没有可用的端口:
- 不会重定向到 HTTPS。
- 中间件记录“无法确定用于重定向的 https 端口”警告。
使用以下任一方法指定 HTTPS 端口:
设置
https_port
主机设置:在主机配置中。
通过设置
ASPNETCORE_HTTPS_PORT
环境变量。通过在
appsettings.json
中添加顶级条目:{ "https_port": 443, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*" }
使用 ASPNETCORE_URLS 环境变量指示使用安全方案的端口。 该环境变量配置服务器。 中间件通过 IServerAddressesFeature 间接发现 HTTPS 端口。 此方法在反向代理部署中不起作用。
ASP.NET Core Web 模板在
Properties/launchsettings.json
中为 Kestrel 和 IIS Express 设置 HTTPS URL。launchsettings.json
仅在本地计算机上使用。为 Kestrel 服务器或 HTTP.sys 服务器的面向公众的边缘部署配置 HTTPS URL 终结点。 该应用仅使用一个 HTTPS 端口。 中间件通过 IServerAddressesFeature 发现该端口。
注意
当应用在反向代理配置中运行时,IServerAddressesFeature 不可用。 使用本部分中所述的其他方法之一设置端口。
Edge 部署
当 Kestrel 或 HTTP.sys 用作面向公众的边缘服务器时,必须将 Kestrel 或 HTTP.sys 配置为对这两者进行侦听:
- 重定向客户端的安全端口(通常在生产环境中为 443,在开发环境中为 5001)。
- 不安全的端口(通常在生产环境中为 80,在开发环境中为 5000)。
客户端必须可以访问不安全的端口,以便应用接收不安全的请求并将客户端重定向到安全端口。
有关详细信息,请参阅 Kestrel终结点配置或 ASP.NET Core 中的 HTTP.sys Web 服务器实现。
部署方案
客户端和服务器之间的任何防火墙还必须打开通信端口供流量使用。
如果在反向代理配置中转发请求,请在调用 HTTPS 重定向中间件之前使用转接头中间件。 转接头中间件使用 X-Forwarded-Proto
标头更新 Request.Scheme
。 使用该中间件,重定向 URI 和其他安全策略可以正常工作。 如果不使用转接头中间件,后端应用可能无法接收到正确的方案并最终进入重定向循环。 常见的最终用户错误消息是发生了太多重定向。
部署到 Azure 应用服务时,请遵循教程:将现有自定义 SSL 证书绑定到 Azure Web 应用中的指导。
选项
以下突出显示的代码调用 AddHttpsRedirection 来配置中间件选项:
using static Microsoft.AspNetCore.Http.StatusCodes;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.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");
});
builder.Services.AddHttpsRedirection(options =>
{
options.RedirectStatusCode = Status307TemporaryRedirect;
options.HttpsPort = 5001;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
仅在更改 HttpsPort
或 RedirectStatusCode
的值时才需要调用 AddHttpsRedirection
。
上述突出显示的代码:
- 将 HttpsRedirectionOptions.RedirectStatusCode 设置为 Status307TemporaryRedirect,这是默认值。 使用 StatusCodes 类的字段进行
RedirectStatusCode
的分配。 - 将 HTTPS 端口设置为 5001。
在生产环境中配置永久性重定向
中间件默认发送包含所有重定向的 Status307TemporaryRedirect。 如果希望在应用处于非开发环境时发送永久性重定向状态代码,请将中间件选项配置包装在非开发环境的条件检查中。
在 Program.cs
中配置服务时:
using static Microsoft.AspNetCore.Http.StatusCodes;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
if (!builder.Environment.IsDevelopment())
{
builder.Services.AddHttpsRedirection(options =>
{
options.RedirectStatusCode = Status308PermanentRedirect;
options.HttpsPort = 443;
});
}
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
HTTPS 重定向中间件替代方法
使用 HTTPS 重定向中间件 (UseHttpsRedirection
) 的替代方法是使用 URL 重写中间件 (AddRedirectToHttps
)。 AddRedirectToHttps
还可以设置执行重定向时的状态码和端口。 有关详细信息,请参阅 URL 重写中间件。
当重定向到 HTTPS 并且不需要其他重定向规则时,建议使用本文所述的 HTTPS 重定向中间件 (UseHttpsRedirection
)。
HTTP 严格传输安全协议 (HSTS)
根据 OWASP,HTTP 严格传输安全 (HSTS) 是一种可选的安全增强功能,由 Web 应用通过使用响应标头来指定。 当支持 HSTS 的浏览器收到此标头时:
- 该浏览器会存储防止通过 HTTP 发送任何通信的域配置。 该浏览器会强制通过 HTTPS 进行所有通信。
- 该浏览器会阻止用户使用不受信任或无效的证书。 该浏览器会禁用允许用户暂时信任此类证书的提示。
由于客户端强制使用 HSTS,因此它存在一些限制:
- 客户端必须支持 HSTS。
- HSTS 需要至少一个成功的 HTTPS 请求才能建立 HSTS 策略。
- 应用程序必须检查每个 HTTP 请求,并重定向或拒绝 HTTP 请求。
ASP.NET Core 使用 UseHsts 扩展方法实现 HSTS。 当应用未处于开发模式时,以下代码会调用 UseHsts
:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
不建议在开发环境中使用 UseHsts
,因为 HSTS 设置对浏览器而言是高度可缓存的。 默认情况下,UseHsts
不包括本地环回地址。
对于首次实现 HTTPS 的生产环境,使用 TimeSpan 方法之一将初始 HstsOptions.MaxAge 设置为较小的值。 如果需要将 HTTPS 基础结构还原为 HTTP,请将值从几小时设置为不超过一天。 确信 HTTPS 配置可持续后,增加 HSTS max-age
值;常用的值是一年。
以下突出显示的代码:
using static Microsoft.AspNetCore.Http.StatusCodes;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.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");
});
builder.Services.AddHttpsRedirection(options =>
{
options.RedirectStatusCode = Status307TemporaryRedirect;
options.HttpsPort = 5001;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
- 设置
Strict-Transport-Security
标头的预加载参数。 RFC HSTS 规范中不包含预加载,但 Web 浏览器支持在新安装时预加载 HSTS 站点。 有关详细信息,请参阅 https://hstspreload.org/。 - 启用 includeSubDomain,它会将 HSTS 策略应用于主机子域。
- 将
Strict-Transport-Security
标头的max-age
参数显式设置为 60 天。 如果未设置,则默认为 30 天。 有关详细信息,请参阅 max-age 指令。 - 将
example.com
添加到要排除的主机列表中。
UseHsts
不包括以下环回主机:
localhost
:IPv4 环回地址。127.0.0.1
:IPv4 环回地址。[::1]
:IPv6 环回地址。
在项目创建时选择退出 HTTPS/HSTS
在一些后端服务场景中,连接安全性是在网络面向公众的边缘处理的,因此无需在每个节点上配置连接安全性。 从 Visual Studio 中的模板或 dotnet new 命令生成的 Web 应用启用 HTTPS 重定向和 HSTS。 对于不需要这些方案的部署,可以在从模板创建应用时选择退出 HTTPS/HSTS。
若要选择退出 HTTPS/HSTS,请执行以下操作:
取消选中“针对 HTTPS 进行配置”复选框。
信任 Windows 和 macOS 上的 ASP.NET Core HTTPS 开发证书
对于 Firefox 浏览器,请参阅下一部分。
.NET Core SDK 包含 HTTPS 开发证书。 该证书是作为首次运行体验的一部分安装的。 例如,dotnet --info
会生成以下输出的变体:
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 开发证书安装到本地用户证书存储。 该证书已安装,但它不受信任。 要信任该证书,请执行一次性步骤来运行 dotnet dev-certs
工具:
dotnet dev-certs https --trust
下面的命令提供有关 dotnet dev-certs
工具的帮助:
dotnet dev-certs https --help
警告
请勿在将被重新分发的环境中创建开发证书,例如容器映像或虚拟机。 这样做可能会导致欺骗和特权提升。 为了帮助防止出现这种情况,请在第一次调用 .NET CLI 之前,将 DOTNET_GENERATE_ASPNET_CERTIFICATE
环境变量设置为 false
。 这将在 CLI 的首次运行体验期间跳过自动生成 ASP.NET Core 开发证书。
使用 Firefox 信任 HTTPS 证书以防止出现 SEC_ERROR_INADEQUATE_KEY_USAGE 错误
Firefox 浏览器使用自己的证书存储,因此不信任 IIS Express 或 Kestrel 开发人员证书。
使用 Firefox 信任 HTTPS 证书有两种方法:创建策略文件或使用 FireFox 浏览器进行配置。 配置该浏览器会创建策略文件,因此这两种方法是等效的。
创建策略文件以使用 Firefox 信任 HTTPS 证书
在以下位置复制策略文件 (policies.json
):
- Windows:
%PROGRAMFILES%\Mozilla Firefox\distribution\
- MacOS:
Firefox.app/Contents/Resources/distribution
- Linux:请参阅本文中的在 Linux 上使用 Firefox 信任证书。
将以下 JSON 添加到 Firefox 策略文件:
{
"policies": {
"Certificates": {
"ImportEnterpriseRoots": true
}
}
}
前面的策略文件使 Firefox 信任证书,这些证书来自 Windows 证书存储中的受信任证书。 下一部分提供了另一种方法来使用 Firefox 浏览器创建上述策略文件。
使用 Firefox 浏览器配置 HTTPS 证书信任
使用以下说明设置 security.enterprise_roots.enabled
= true
:
- 在 FireFox 浏览器中输入
about:config
。 - 如果你接受风险,请选择“接受风险并继续”。
- 选择“全部显示”
- 设置
security.enterprise_roots.enabled
=true
- 退出并重启 Firefox
有关详细信息,请参阅在 Firefox 中设置证书颁发机构 (CA) 和 mozilla/policy-templates/README 文件。
如何为 Docker 设置开发人员证书
请参阅此 GitHub 问题。
在 Linux 上信任 HTTPS 证书
建立信任是特定于发行版和浏览器的。 以下部分提供了针对一些常用发行版和 Chromium 浏览器(Edge 和 Chrome)以及针对 Firefox 的说明。
Ubuntu 信任用于进行服务到服务通信的证书
以下说明不适用于某些 Ubuntu 版本,例如 20.04。 有关详细信息,请参阅 GitHub 问题 dotnet/AspNetCore.Docs #23686。
安装 OpenSSL 1.1.1h 或更高版本。 有关如何更新 OpenSSL 的说明,请参阅你的发行版。
运行以下命令:
dotnet dev-certs https sudo -E dotnet dev-certs https -ep /usr/local/share/ca-certificates/aspnet/https.crt --format PEM sudo update-ca-certificates
前面的命令:
- 确保创建了当前用户的开发人员证书。
- 使用当前用户的环境导出具有
ca-certificates
文件夹所需的提升权限的证书。 - 删除
-E
标志会导出根用户证书,并根据需要生成它。 每个新生成的证书都有不同的指纹。 以根用户身份运行时,不需要sudo
和-E
。
上述命令中的路径特定于 Ubuntu。 对于其他发行版,请选择相应的路径或使用证书颁发机构 (CA) 的路径。
在 Linux 上使用 Edge 或 Chrome 信任 HTTPS 证书
对于 Linux 上的 chromium 浏览器:
为你的发行版安装
libnss3-tools
。创建
$HOME/.pki/nssdb
文件夹或验证计算机上是否存在该文件夹。使用以下命令导出证书:
dotnet dev-certs https sudo -E dotnet dev-certs https -ep /usr/local/share/ca-certificates/aspnet/https.crt --format PEM
上述命令中的路径特定于 Ubuntu。 对于其他发行版,请选择相应的路径或使用证书颁发机构 (CA) 的路径。
运行以下命令:
certutil -d sql:$HOME/.pki/nssdb -A -t "P,," -n localhost -i /usr/local/share/ca-certificates/aspnet/https.crt
退出并重启浏览器。
在 Linux 上使用 Firefox 信任证书
使用以下命令导出证书:
dotnet dev-certs https sudo -E dotnet dev-certs https -ep /usr/local/share/ca-certificates/aspnet/https.crt --format PEM
上述命令中的路径特定于 Ubuntu。 对于其他发行版,请选择相应的路径或使用证书颁发机构 (CA) 的路径。
使用以下命令在
/usr/lib/firefox/distribution/policies.json
创建 JSON 文件:
cat <<EOF | sudo tee /usr/lib/firefox/distribution/policies.json
{
"policies": {
"Certificates": {
"Install": [
"/usr/local/share/ca-certificates/aspnet/https.crt"
]
}
}
}
EOF
注意:Ubuntu 21.10 Firefox 作为快照包提供,安装文件夹为 /snap/firefox/current/usr/lib/firefox
。
有关使用浏览器配置策略文件的替代方法,请参阅本文中的使用 Firefox 浏览器配置 HTTPS 证书信任。
使用 Fedora 34 信任证书
请参阅:
- 此 GitHub 注释
- Fedora:使用共享系统证书
- 在 Fedora 上设置 .NET 开发环境。
使用其他发行版信任证书
请参阅此 GitHub 问题。
信任来自适用于 Linux 的 Windows 子系统的 HTTPS 证书
以下说明不适用于某些 Linux 发行版,例如 Ubuntu 20.04。 有关详细信息,请参阅 GitHub 问题 dotnet/AspNetCore.Docs #23686。
适用于 Linux 的 Windows 子系统 (WSL) 生成 HTTPS 自签名开发证书,默认情况下,该证书在 Windows 中不受信任。 让 Windows 信任 WSL 证书的最简单方法是将 WSL 配置为使用与 Windows 相同的证书:
在 Windows 上,将开发者证书导出到文件:
dotnet dev-certs https -ep https.pfx -p $CREDENTIAL_PLACEHOLDER$ --trust
其中
$CREDENTIAL_PLACEHOLDER$
是密码。在 WSL 窗口中,将导出的证书导入 WSL 实例:
dotnet dev-certs https --clean --import <<path-to-pfx>> --password $CREDENTIAL_PLACEHOLDER$
上述方法是按每个证书和每个 WSL 发行版进行的一次性操作。 这比反复导出证书更容易。 如果在 Windows 上更新或重新生成证书,则可能需要再次运行上述命令。
排查证书问题,例如证书不受信任
如果 ASP.NET Core HTTPS 开发证书已安装且受信任,但仍收到证书不受信任的浏览器警告,则本部分可提供帮助。 ASP.NET Core HTTPS 开发证书由 Kestrel 使用。
若要修复 IIS Express 证书,请参阅此 Stackoverflow 问题。
所有平台 - 证书不受信任
运行以下命令:
dotnet dev-certs https --clean
dotnet dev-certs https --trust
关闭所有打开的浏览器实例。 在应用中打开一个新的浏览器窗口。 证书信任由浏览器缓存。
dotnet dev-certs https --clean 失败
上述命令可解决大多数浏览器信任问题。 如果浏览器仍不信任证书,请按照以下特定于该平台的建议操作。
Docker - 证书不受信任
- 删除 C:\Users{USER}\AppData\Roaming\ASP.NET\Https 文件夹。
- 清理解决方案。 删除 bin 和 obj 文件夹。
- 重启开发工具。 例如,Visual Studio 或 Visual Studio Code。
Windows - 证书不受信任
- 检查证书存储中的证书。 在
Current User > Personal > Certificates
和Current User > Trusted root certification authorities > Certificates
下都应有一个具有ASP.NET Core HTTPS development certificate
易记名称的localhost
证书 - 从个人和受信任的根证书颁发机构中删除所有找到的证书。 请勿删除 IIS Express localhost 证书。
- 运行以下命令:
dotnet dev-certs https --clean
dotnet dev-certs https --trust
关闭所有打开的浏览器实例。 在应用中打开一个新的浏览器窗口。
OS X - 证书不受信任
- 打开“密钥链访问”。
- 选择“系统密钥链”。
- 检查是否存在 localhost 证书。
- 检查其图标上是否包含
+
符号,以表明它对于所有用户而言均受信任。 - 从系统密钥链中删除证书。
- 运行以下命令:
dotnet dev-certs https --clean
dotnet dev-certs https --trust
关闭所有打开的浏览器实例。 在应用中打开一个新的浏览器窗口。
若要排查 Visual Studio 的证书问题,请参阅使用 IIS Express 时出现 HTTPS 错误 (dotnet/AspNetCore #16892)。
Linux 证书不受信任
检查配置为信任的证书是否为 Kestrel 服务器将使用的用户 HTTPS 开发人员证书。
在以下位置检查当前用户默认的 HTTPS 开发人员 Kestrel 证书:
ls -la ~/.dotnet/corefx/cryptography/x509stores/my
HTTPS 开发人员 Kestrel 证书文件是 SHA1 指纹。 当通过 dotnet dev-certs https --clean
删除该文件时,会根据需要使用不同的指纹重新生成。
使用以下命令检查导出证书的指纹是否匹配:
openssl x509 -noout -fingerprint -sha1 -inform pem -in /usr/local/share/ca-certificates/aspnet/https.crt
如果该证书不匹配,则可能是以下情况之一:
- 旧证书。
- 为根用户导出了开发人员证书。 对于这种情况,请导出证书。
可在以下位置检查根用户证书:
ls -la /root/.dotnet/corefx/cryptography/x509stores/my
将 IIS Express SSL 证书与 Visual Studio 一起使用
若要解决 IIS Express 证书的问题,请在 Visual Studio 安装程序中选择“修复”。 有关详细信息,请参阅此 GitHub 问题。
组策略可阻止信任自签名证书
在某些情况下,组策略可能会阻止信任自签名证书。 有关详细信息,请参阅此 GitHub 问题。
其他信息
注意
如果你使用的是 .NET 9 SDK 或更高版本,请参阅本文的 .NET 9 版本中更新的 Linux 操作流程。
警告
API 项目
请勿在接收敏感信息的 Web API 上使用 RequireHttpsAttributeRequireHttpsAttribute。 RequireHttpsAttribute
使用 HTTP 状态代码将浏览器从 HTTP 重定向到 HTTPS。 API 客户端可能不理解或不遵循从 HTTP 到 HTTPS 的重定向。 此类客户端可以通过 HTTP 发送信息。 Web API 应该执行以下操作之一:
- 不侦听 HTTP。
- 关闭状态码为 400(错误请求)的连接并且不处理请求。
若要在 API 中禁用 HTTP 重定向,请设置 ASPNETCORE_URLS
环境变量或使用 --urls
命令行标志。 有关详细信息,请参阅 Andrew Lock 撰写的在 ASP.NET Core 中使用多个环境和为 ASP.NET Core 应用设置 URL 的 8 种方法。
HSTS 和 API 项目
默认 API 项目不包括 HSTS,因为 HSTS 通常是浏览器专用的指令。 其他调用方(例如电话或桌面应用)不遵循该指令。 即使在浏览器中,通过 HTTP 对 API 的单个经过身份验证的调用在不安全的网络中也会有风险。 安全的方法是将 API 项目配置为仅通过 HTTPS 进行侦听和响应。
HTTP 重定向到 HTTPS 会导致 CORS 预检请求出现 ERR_INVALID_REDIRECT
在 CORS 预检请求时,使用由 UseHttpsRedirection 重定向到 HTTPS 的 HTTP 请求终结点失败,错误为 ERR_INVALID_REDIRECT
。
API 项目可以拒绝 HTTP 请求,而不是使用 UseHttpsRedirection
将请求重定向到 HTTPS。
需要 HTTPS
建议生产 ASP.NET Core web 应用使用:
- HTTPS 重定向中间件 (UseHttpsRedirection) 将 HTTP 请求重定向到 HTTPS。
- HSTS 中间件 (UseHsts) 将 HTTP 严格传输安全协议 (HSTS) 标头发送到客户端。
注意
在反向代理配置中部署的应用允许代理来处理连接安全性 (HTTPS)。 如果该代理也处理 HTTPS 重定向,则无需使用 HTTPS 重定向中间件。 如果代理服务器也处理写入 HSTS 标头(例如,IIS 10.0 (1709) 或更高版本中的本机 HSTS 支持),则应用不需要使用 HSTS 中间件。 有关详细信息,请参阅项目创建时选择退出 HTTPS/HSTS。
UseHttpsRedirection
以下代码调用 Program.cs
文件中的 UseHttpsRedirection:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
上述突出显示的代码:
- 使用默认 HttpsRedirectionOptions.RedirectStatusCode (Status307TemporaryRedirect) 。
- 除非被
ASPNETCORE_HTTPS_PORT
环境变量或 IServerAddressesFeature 替代,否则使用默认 HttpsRedirectionOptions.HttpsPort (null)。
建议使用临时重定向,而不使用永久性重定向。 链接缓存会导致开发环境中的行为不稳定。 如果希望在应用处于非开发环境时发送永久性重定向状态代码,请参阅在生产环境中配置永久性重定向部分。 建议使用 HSTS 向客户端发出信号,即应仅将安全资源请求发送到应用(仅在生产环境中)。
端口配置
中间件必须有可用的端口才能将不安全的请求重定向到 HTTPS。 如果没有可用的端口:
- 不会重定向到 HTTPS。
- 中间件记录“无法确定用于重定向的 https 端口”警告。
使用以下任一方法指定 HTTPS 端口:
设置
https_port
主机设置:在主机配置中。
通过设置
ASPNETCORE_HTTPS_PORT
环境变量。通过在
appsettings.json
中添加顶级条目:{ "https_port": 443, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*" }
使用 ASPNETCORE_URLS 环境变量指示使用安全方案的端口。 该环境变量配置服务器。 中间件通过 IServerAddressesFeature 间接发现 HTTPS 端口。 此方法在反向代理部署中不起作用。
ASP.NET Core Web 模板在
Properties/launchsettings.json
中为 Kestrel 和 IIS Express 设置 HTTPS URL。launchsettings.json
仅在本地计算机上使用。为 Kestrel 服务器或 HTTP.sys 服务器的面向公众的边缘部署配置 HTTPS URL 终结点。 该应用仅使用一个 HTTPS 端口。 中间件通过 IServerAddressesFeature 发现该端口。
注意
当应用在反向代理配置中运行时,IServerAddressesFeature 不可用。 使用本部分中所述的其他方法之一设置端口。
Edge 部署
当 Kestrel 或 HTTP.sys 用作面向公众的边缘服务器时,必须将 Kestrel 或 HTTP.sys 配置为对这两者进行侦听:
- 重定向客户端的安全端口(通常在生产环境中为 443,在开发环境中为 5001)。
- 不安全的端口(通常在生产环境中为 80,在开发环境中为 5000)。
客户端必须可以访问不安全的端口,以便应用接收不安全的请求并将客户端重定向到安全端口。
有关详细信息,请参阅 Kestrel终结点配置或 ASP.NET Core 中的 HTTP.sys Web 服务器实现。
部署方案
客户端和服务器之间的任何防火墙还必须打开通信端口供流量使用。
如果在反向代理配置中转发请求,请在调用 HTTPS 重定向中间件之前使用转接头中间件。 转接头中间件使用 X-Forwarded-Proto
标头更新 Request.Scheme
。 使用该中间件,重定向 URI 和其他安全策略可以正常工作。 如果不使用转接头中间件,后端应用可能无法接收到正确的方案并最终进入重定向循环。 常见的最终用户错误消息是发生了太多重定向。
部署到 Azure 应用服务时,请遵循教程:将现有自定义 SSL 证书绑定到 Azure Web 应用中的指导。
选项
以下突出显示的代码调用 AddHttpsRedirection 来配置中间件选项:
using static Microsoft.AspNetCore.Http.StatusCodes;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.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");
});
builder.Services.AddHttpsRedirection(options =>
{
options.RedirectStatusCode = Status307TemporaryRedirect;
options.HttpsPort = 5001;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
仅在更改 HttpsPort
或 RedirectStatusCode
的值时才需要调用 AddHttpsRedirection
。
上述突出显示的代码:
- 将 HttpsRedirectionOptions.RedirectStatusCode 设置为 Status307TemporaryRedirect,这是默认值。 使用 StatusCodes 类的字段进行
RedirectStatusCode
的分配。 - 将 HTTPS 端口设置为 5001。
在生产环境中配置永久性重定向
中间件默认发送包含所有重定向的 Status307TemporaryRedirect。 如果希望在应用处于非开发环境时发送永久性重定向状态代码,请将中间件选项配置包装在非开发环境的条件检查中。
在 Program.cs
中配置服务时:
using static Microsoft.AspNetCore.Http.StatusCodes;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
if (!builder.Environment.IsDevelopment())
{
builder.Services.AddHttpsRedirection(options =>
{
options.RedirectStatusCode = Status308PermanentRedirect;
options.HttpsPort = 443;
});
}
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
HTTPS 重定向中间件替代方法
使用 HTTPS 重定向中间件 (UseHttpsRedirection
) 的替代方法是使用 URL 重写中间件 (AddRedirectToHttps
)。 AddRedirectToHttps
还可以设置执行重定向时的状态码和端口。 有关详细信息,请参阅 URL 重写中间件。
当重定向到 HTTPS 并且不需要其他重定向规则时,建议使用本文所述的 HTTPS 重定向中间件 (UseHttpsRedirection
)。
HTTP 严格传输安全协议 (HSTS)
根据 OWASP,HTTP 严格传输安全 (HSTS) 是一种可选的安全增强功能,由 Web 应用通过使用响应标头来指定。 当支持 HSTS 的浏览器收到此标头时:
- 该浏览器会存储防止通过 HTTP 发送任何通信的域配置。 该浏览器会强制通过 HTTPS 进行所有通信。
- 该浏览器会阻止用户使用不受信任或无效的证书。 该浏览器会禁用允许用户暂时信任此类证书的提示。
由于客户端强制使用 HSTS,因此它存在一些限制:
- 客户端必须支持 HSTS。
- HSTS 需要至少一个成功的 HTTPS 请求才能建立 HSTS 策略。
- 应用程序必须检查每个 HTTP 请求,并重定向或拒绝 HTTP 请求。
ASP.NET Core 使用 UseHsts 扩展方法实现 HSTS。 当应用未处于开发模式时,以下代码会调用 UseHsts
:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
不建议在开发环境中使用 UseHsts
,因为 HSTS 设置对浏览器而言是高度可缓存的。 默认情况下,UseHsts
不包括本地环回地址。
对于首次实现 HTTPS 的生产环境,使用 TimeSpan 方法之一将初始 HstsOptions.MaxAge 设置为较小的值。 如果需要将 HTTPS 基础结构还原为 HTTP,请将值从几小时设置为不超过一天。 确信 HTTPS 配置可持续后,增加 HSTS max-age
值;常用的值是一年。
以下突出显示的代码:
using static Microsoft.AspNetCore.Http.StatusCodes;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.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");
});
builder.Services.AddHttpsRedirection(options =>
{
options.RedirectStatusCode = Status307TemporaryRedirect;
options.HttpsPort = 5001;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
- 设置
Strict-Transport-Security
标头的预加载参数。 RFC HSTS 规范中不包含预加载,但 Web 浏览器支持在新安装时预加载 HSTS 站点。 有关详细信息,请参阅 https://hstspreload.org/。 - 启用 includeSubDomain,它会将 HSTS 策略应用于主机子域。
- 将
Strict-Transport-Security
标头的max-age
参数显式设置为 60 天。 如果未设置,则默认为 30 天。 有关详细信息,请参阅 max-age 指令。 - 将
example.com
添加到要排除的主机列表中。
UseHsts
不包括以下环回主机:
localhost
:IPv4 环回地址。127.0.0.1
:IPv4 环回地址。[::1]
:IPv6 环回地址。
在项目创建时选择退出 HTTPS/HSTS
在一些后端服务场景中,连接安全性是在网络面向公众的边缘处理的,因此无需在每个节点上配置连接安全性。 从 Visual Studio 中的模板或 dotnet new 命令生成的 Web 应用启用 HTTPS 重定向和 HSTS。 对于不需要这些方案的部署,可以在从模板创建应用时选择退出 HTTPS/HSTS。
若要选择退出 HTTPS/HSTS,请执行以下操作:
取消选中“针对 HTTPS 进行配置”复选框。
信任 Windows 和 macOS 上的 ASP.NET Core HTTPS 开发证书
对于 Firefox 浏览器,请参阅下一部分。
.NET Core SDK 包含 HTTPS 开发证书。 该证书是作为首次运行体验的一部分安装的。 例如,dotnet --info
会生成以下输出的变体:
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 开发证书安装到本地用户证书存储。 该证书已安装,但它不受信任。 要信任该证书,请执行一次性步骤来运行 dotnet dev-certs
工具:
dotnet dev-certs https --trust
下面的命令提供有关 dotnet dev-certs
工具的帮助:
dotnet dev-certs https --help
警告
请勿在将被重新分发的环境中创建开发证书,例如容器映像或虚拟机。 这样做可能会导致欺骗和特权提升。 为了帮助防止出现这种情况,请在第一次调用 .NET CLI 之前,将 DOTNET_GENERATE_ASPNET_CERTIFICATE
环境变量设置为 false
。 这将在 CLI 的首次运行体验期间跳过自动生成 ASP.NET Core 开发证书。
使用 Firefox 信任 HTTPS 证书以防止出现 SEC_ERROR_INADEQUATE_KEY_USAGE 错误
Firefox 浏览器使用自己的证书存储,因此不信任 IIS Express 或 Kestrel 开发人员证书。
使用 Firefox 信任 HTTPS 证书有两种方法:创建策略文件或使用 FireFox 浏览器进行配置。 配置该浏览器会创建策略文件,因此这两种方法是等效的。
创建策略文件以使用 Firefox 信任 HTTPS 证书
在以下位置复制策略文件 (policies.json
):
- Windows:
%PROGRAMFILES%\Mozilla Firefox\distribution\
- MacOS:
Firefox.app/Contents/Resources/distribution
- Linux:请参阅本文中的在 Linux 上使用 Firefox 信任证书。
将以下 JSON 添加到 Firefox 策略文件:
{
"policies": {
"Certificates": {
"ImportEnterpriseRoots": true
}
}
}
前面的策略文件使 Firefox 信任证书,这些证书来自 Windows 证书存储中的受信任证书。 下一部分提供了另一种方法来使用 Firefox 浏览器创建上述策略文件。
使用 Firefox 浏览器配置 HTTPS 证书信任
使用以下说明设置 security.enterprise_roots.enabled
= true
:
- 在 FireFox 浏览器中输入
about:config
。 - 如果你接受风险,请选择“接受风险并继续”。
- 选择“全部显示”
- 设置
security.enterprise_roots.enabled
=true
- 退出并重启 Firefox
有关详细信息,请参阅在 Firefox 中设置证书颁发机构 (CA) 和 mozilla/policy-templates/README 文件。
如何为 Docker 设置开发人员证书
请参阅此 GitHub 问题。
在 Linux 上信任 HTTPS 证书
建立信任是特定于发行版和浏览器的。 以下部分提供了针对一些常用发行版和 Chromium 浏览器(Edge 和 Chrome)以及针对 Firefox 的说明。
在 Linux 上使用 linux-dev-certs 信任 HTTPS 证书
linux-dev-certs 是一种开源、社区支持的 .NET 全局工具,可快捷地在 Linux 上创建和信任开发人员证书。 该工具不由 Microsoft 进行支持或维护。
以下命令安装该工具并创建受信任的开发人员证书:
dotnet tool update -g linux-dev-certs
dotnet linux-dev-certs install
有关详细信息或要报告问题,请参阅 linux-dev-certs GitHub 存储库。
Ubuntu 信任用于进行服务到服务通信的证书
以下说明不适用于某些 Ubuntu 版本,例如 20.04。 有关详细信息,请参阅 GitHub 问题 dotnet/AspNetCore.Docs #23686。
安装 OpenSSL 1.1.1h 或更高版本。 有关如何更新 OpenSSL 的说明,请参阅你的发行版。
运行以下命令:
dotnet dev-certs https sudo -E dotnet dev-certs https -ep /usr/local/share/ca-certificates/aspnet/https.crt --format PEM sudo update-ca-certificates
前面的命令:
- 确保创建了当前用户的开发人员证书。
- 使用当前用户的环境导出具有
ca-certificates
文件夹所需的提升权限的证书。 - 删除
-E
标志会导出根用户证书,并根据需要生成它。 每个新生成的证书都有不同的指纹。 以根用户身份运行时,不需要sudo
和-E
。
上述命令中的路径特定于 Ubuntu。 对于其他发行版,请选择相应的路径或使用证书颁发机构 (CA) 的路径。
在 Linux 上使用 Edge 或 Chrome 信任 HTTPS 证书
对于 Linux 上的 chromium 浏览器:
为你的发行版安装
libnss3-tools
。创建
$HOME/.pki/nssdb
文件夹或验证计算机上是否存在该文件夹。使用以下命令导出证书:
dotnet dev-certs https sudo -E dotnet dev-certs https -ep /usr/local/share/ca-certificates/aspnet/https.crt --format PEM
上述命令中的路径特定于 Ubuntu。 对于其他发行版,请选择相应的路径或使用证书颁发机构 (CA) 的路径。
运行以下命令:
certutil -d sql:$HOME/.pki/nssdb -A -t "P,," -n localhost -i /usr/local/share/ca-certificates/aspnet/https.crt
退出并重启浏览器。
在 Linux 上使用 Firefox 信任证书
使用以下命令导出证书:
dotnet dev-certs https sudo -E dotnet dev-certs https -ep /usr/local/share/ca-certificates/aspnet/https.crt --format PEM
上述命令中的路径特定于 Ubuntu。 对于其他发行版,请选择相应的路径或使用证书颁发机构 (CA) 的路径。
使用以下命令在
/usr/lib/firefox/distribution/policies.json
创建 JSON 文件:
cat <<EOF | sudo tee /usr/lib/firefox/distribution/policies.json
{
"policies": {
"Certificates": {
"Install": [
"/usr/local/share/ca-certificates/aspnet/https.crt"
]
}
}
}
EOF
注意:Ubuntu 21.10 Firefox 作为快照包提供,安装文件夹为 /snap/firefox/current/usr/lib/firefox
。
有关使用浏览器配置策略文件的替代方法,请参阅本文中的使用 Firefox 浏览器配置 HTTPS 证书信任。
使用 Fedora 34 信任证书
请参阅:
- 此 GitHub 注释
- Fedora:使用共享系统证书
- 在 Fedora 上设置 .NET 开发环境。
使用其他发行版信任证书
请参阅此 GitHub 问题。
信任来自适用于 Linux 的 Windows 子系统的 HTTPS 证书
以下说明不适用于某些 Linux 发行版,例如 Ubuntu 20.04。 有关详细信息,请参阅 GitHub 问题 dotnet/AspNetCore.Docs #23686。
适用于 Linux 的 Windows 子系统 (WSL) 生成 HTTPS 自签名开发证书,默认情况下,该证书在 Windows 中不受信任。 让 Windows 信任 WSL 证书的最简单方法是将 WSL 配置为使用与 Windows 相同的证书:
在 Windows 上,将开发者证书导出到文件:
dotnet dev-certs https -ep https.pfx -p $CREDENTIAL_PLACEHOLDER$ --trust
其中
$CREDENTIAL_PLACEHOLDER$
是密码。在 WSL 窗口中,将导出的证书导入 WSL 实例:
dotnet dev-certs https --clean --import <<path-to-pfx>> --password $CREDENTIAL_PLACEHOLDER$
上述方法是按每个证书和每个 WSL 发行版进行的一次性操作。 这比反复导出证书更容易。 如果在 Windows 上更新或重新生成证书,则可能需要再次运行上述命令。
排查证书问题,例如证书不受信任
如果 ASP.NET Core HTTPS 开发证书已安装且受信任,但仍收到证书不受信任的浏览器警告,则本部分可提供帮助。 ASP.NET Core HTTPS 开发证书由 Kestrel 使用。
若要修复 IIS Express 证书,请参阅此 Stackoverflow 问题。
所有平台 - 证书不受信任
运行以下命令:
dotnet dev-certs https --clean
dotnet dev-certs https --trust
关闭所有打开的浏览器实例。 在应用中打开一个新的浏览器窗口。 证书信任由浏览器缓存。
dotnet dev-certs https --clean 失败
上述命令可解决大多数浏览器信任问题。 如果浏览器仍不信任证书,请按照以下特定于该平台的建议操作。
Docker - 证书不受信任
- 删除 C:\Users{USER}\AppData\Roaming\ASP.NET\Https 文件夹。
- 清理解决方案。 删除 bin 和 obj 文件夹。
- 重启开发工具。 例如,Visual Studio 或 Visual Studio Code。
Windows - 证书不受信任
- 检查证书存储中的证书。 在
Current User > Personal > Certificates
和Current User > Trusted root certification authorities > Certificates
下都应有一个具有ASP.NET Core HTTPS development certificate
易记名称的localhost
证书 - 从个人和受信任的根证书颁发机构中删除所有找到的证书。 请勿删除 IIS Express localhost 证书。
- 运行以下命令:
dotnet dev-certs https --clean
dotnet dev-certs https --trust
关闭所有打开的浏览器实例。 在应用中打开一个新的浏览器窗口。
OS X - 证书不受信任
- 打开“密钥链访问”。
- 选择“系统密钥链”。
- 检查是否存在 localhost 证书。
- 检查其图标上是否包含
+
符号,以表明它对于所有用户而言均受信任。 - 从系统密钥链中删除证书。
- 运行以下命令:
dotnet dev-certs https --clean
dotnet dev-certs https --trust
关闭所有打开的浏览器实例。 在应用中打开一个新的浏览器窗口。
若要排查 Visual Studio 的证书问题,请参阅使用 IIS Express 时出现 HTTPS 错误 (dotnet/AspNetCore #16892)。
Linux 证书不受信任
检查配置为信任的证书是否为 Kestrel 服务器将使用的用户 HTTPS 开发人员证书。
在以下位置检查当前用户默认的 HTTPS 开发人员 Kestrel 证书:
ls -la ~/.dotnet/corefx/cryptography/x509stores/my
HTTPS 开发人员 Kestrel 证书文件是 SHA1 指纹。 当通过 dotnet dev-certs https --clean
删除该文件时,会根据需要使用不同的指纹重新生成。
使用以下命令检查导出证书的指纹是否匹配:
openssl x509 -noout -fingerprint -sha1 -inform pem -in /usr/local/share/ca-certificates/aspnet/https.crt
如果该证书不匹配,则可能是以下情况之一:
- 旧证书。
- 为根用户导出了开发人员证书。 对于这种情况,请导出证书。
可在以下位置检查根用户证书:
ls -la /root/.dotnet/corefx/cryptography/x509stores/my
将 IIS Express SSL 证书与 Visual Studio 一起使用
若要解决 IIS Express 证书的问题,请在 Visual Studio 安装程序中选择“修复”。 有关详细信息,请参阅此 GitHub 问题。
组策略可阻止信任自签名证书
在某些情况下,组策略可能会阻止信任自签名证书。 有关详细信息,请参阅此 GitHub 问题。