| [ Web Proxy ] |
| Viewing: https://aka.ms/aspnet/https-trust-dev-cert | [Back] [Original] |
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
By David Galvan and Rick Anderson
To enforce incoming requests to your ASP.NET Core apps to use HTTPS/TLS, you can:
No API can prevent a client from sending sensitive data on the first request.
This article describes how to configure your ASP.NET Core apps to require HTTPS/TLS or redirect HTTP requests to HTTPS/TLS for secure interaction. Troubleshooting steps are provided for various platforms to resolve untrusted certificate issues.
Projects that use Web APIs should either:
To disable HTTP redirection in an API, set the ASPNETCORE_URLS environment variable or use the --urls command line flag. For more information, see ASP.NET Core runtime environments and 8 ways to set the URLs for an ASP.NET Core app by Andrew Lock.
Warning
Do not use RequireHttpsAttribute on Web APIs that receive sensitive information.
RequireHttpsAttribute uses HTTP status codes to redirect browsers from HTTP to HTTPS.
API clients might not understand or obey redirects from HTTP to HTTPS, and they might send information over HTTP.
The secure approach for HTTP Strict Transport Security (HSTS) protocol is to configure API projects to only listen to and respond over HTTPS.
Warning
The default API projects don't include HSTS because it's generally a browser only instruction. Other callers, such as phone or desktop apps, do not obey the instruction. Even within browsers, a single authenticated call to an API over HTTP has risks on insecure networks.
When a request to an endpoint using HTTP is redirected to HTTPS with the UseHttpsRedirection method, the redirection fails with the ERR_INVALID_REDIRECT error on the CORS preflight request.
API projects can reject HTTP requests rather than use the UseHttpsRedirection method to redirect requests to HTTPS.
For production ASP.NET Core web apps, the following approach is recommended:
To redirect HTTP requests to HTTPS, use HTTPS redirection middleware (UseHttpsRedirection).
To send HSTS headers to clients, use HSTS middleware via the UseHsts method.
Note
Apps deployed in a reverse proxy configuration allow the proxy to handle connection security (HTTPS). If the proxy also handles HTTPS redirection, there's no need to use HTTPS redirection middleware. If the proxy server also handles writing HSTS headers (for example, native HSTS support in Internet Information Services (IIS) 10.0 version 1709 or later), then the app doesn't require HSTS middleware. For more information, see Opt-out of HTTPS/HSTS on project creation.
UseHttpsRedirection)The following code calls the UseHttpsRedirection method in the Program.cs file:
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();
The preceding highlighted code:
ASPNETCORE_HTTPS_PORT environment variable or IServerAddressesFeature.The recommended approach is to use 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. Use HSTS to signal to clients that only secure resource requests should be sent to the app (only in production).
Note
Don't confuse the HTTPS_PORT configuration key and ASPNETCORE_HTTPS_PORT environment variable, which set the port for HTTPS redirection middleware, with the HTTPS_PORTS configuration key and ASPNETCORE_HTTPS_PORTS environment variable, which set the ports for Kestrel/HTTP.sys endpoint configuration.
A port must be available for the middleware to redirect an insecure request to HTTPS. If no port is available:
Specify the HTTPS port by using any of the following approaches:
Set the https_port host setting:
In host configuration.
By setting the ASPNETCORE_HTTPS_PORT environment variable.
By adding a top-level entry in the appsettings.json file:
{
"https_port": 443,
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
Indicate a port with the secure scheme by using the ASPNETCORE_URLS environment variable. The environment variable configures the server. The middleware indirectly discovers the HTTPS port via IServerAddressesFeature. This approach doesn't work in reverse proxy deployments.
The ASP.NET Core web templates set an HTTPS URL in the Properties/launchsettings.json file for both Kestrel and IIS Express. The launchsettings.json file is used on the local machine only.
Configure an HTTPS URL endpoint for a public-facing edge deployment of Kestrel server or HTTP.sys server. Only one HTTPS port is used by the app. The middleware discovers the port via IServerAddressesFeature.
Note
When an app runs in a reverse proxy configuration, IServerAddressesFeature isn't available. Set the port by using one of the other approaches described in this section.
When Kestrel or HTTP.sys is used as a public-facing edge server, Kestrel or HTTP.sys must be configured to listen on both:
The insecure port must be accessible by the client for the app to receive an insecure request and redirect the client to the secure port.
For more information, see Kestrel endpoint configuration or HTTP.sys web server implementation in ASP.NET Core.
Any firewall between the client and server must also have communication ports open for traffic.
If requests are forwarded in a reverse proxy configuration, use forwarded headers middleware before calling HTTPS redirection middleware. Forwarded headers middleware updates the Request.Scheme by using the X-Forwarded-Proto header. The middleware permits redirect URIs and other security policies to work correctly. When forwarded headers middleware isn't used, the back-end app might not receive the correct scheme and get caught in a redirect loop. A common end user error message is there are too many redirects.
When deploying to Azure App Service, follow the guidance in Enable HTTPS for a custom domain in Azure App Service.
The following highlighted code calls the AddHttpsRedirection method to configure middleware options:
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();
Calling AddHttpsRedirection is only necessary to change the values of HttpsPort or RedirectStatusCode.
The preceding highlighted code:
RedirectStatusCode.The middleware defaults to sending a Status307TemporaryRedirect code 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.
The following code shows configuration of services in the Program.cs file:
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();
An alternative to using HTTPS redirection middleware (with the UseHttpsRedirection method) is to use URL rewriting middleware (via the AddRedirectToHttps method). AddRedirectToHttps can also set the status code and port when the redirect is executed. For more information, see URL rewriting middleware.
When the app redirects to HTTPS without the requirement for other redirect rules, the recommendation is to use HTTPS redirection middleware (UseHttpsRedirection) as described in this article.
Per OWASP, HSTS is an opt-in security enhancement specified by a web app via a response header. When a browser that supports HSTS receives this header:
Because the client enforces HSTS, there are some limitations:
ASP.NET Core implements HSTS with the UseHsts extension method. The following code calls UseHsts when the app isn't in development mode:
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 isn't recommended in development because the HSTS settings are highly cacheable by browsers. By default, UseHsts excludes the local loopback address.
For production environments that are implementing HTTPS for the first time, set the initial HstsOptions.MaxAge property value to a small amount by using one of the TimeSpan methods. Set the value from hours to no more than a single day, in case you need to revert the HTTPS infrastructure to HTTP. After you're confident in the sustainability of the HTTPS configuration, increase the HSTS max-age value (commonly, one year).
The following highlighted code:
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 header. Preload isn't part of the RFC 6797 HSTS specification. Web browsers support preload of HSTS sites on fresh install. For more information, see https://hstspreload.org/.includeSubDomain directive, which applies the HSTS policy to host subdomains. For more information, see RFC 6797 HSTS specification (Section 6.1.2).max-age parameter of the Strict-Transport-Security header to 60 days. If not set, it defaults to 30 days. For more information, see the max-age directive in RFC 6797 HSTS specification (Section 6.1.1).example.com to the list of hosts to exclude.UseHsts excludes the following loopback hosts:
localhost: The IPv4 loopback address.127.0.0.1: The IPv4 loopback address.[::1]: The IPv6 loopback address.In some back-end 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 apps that are generated from the templates in Visual Studio or from the dotnet new command enable HTTPS redirection and HSTS. For deployments that don't require these scenarios, you can opt out of HTTPS/HSTS when the app is created from the template.
To opt out of HTTPS/HSTS:
When you create a new ASP.NET Core web app, unselect the Configure for HTTPS option:
Use the --no-https option with the dotnet new webapp command, for example:
dotnet new webapp --no-https
The .NET SDK includes an HTTPS development certificate. The certificate is installed as part of the first-run experience. For example, the dotnet --info command produces a variation of the following output:
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.
Installing the .NET SDK installs the ASP.NET Core HTTPS development certificate to the local user certificate store. The certificate is installed, but it isn't trusted. To trust the certificate, perform the one-time step to run the dotnet dev-certs tool:
dotnet dev-certs https --trust
The following command provides help on the dotnet dev-certs tool:
dotnet dev-certs https --help
Warning
Don't create a development certificate in an environment planned for redistribution, such as a container image or virtual machine. This scenario can lead to spoofing and elevation of privilege. To help prevent this situation, set the DOTNET_GENERATE_ASPNET_CERTIFICATE environment variable to false before calling the .NET CLI for the first time. This approach skips the automatic generation of the ASP.NET Core development certificate during the CLI's first-run experience.
To configure the developer certificate for Docker, see GitHub dotnet/aspnetcore.docs issue #6199 - How to set up the dev certificate when using Docker in development.
Linux distributions differ substantially in how they mark certificates as trusted.
The dotnet dev-certs tool is expected to be broadly applicable, but official support is available for Ubuntu and Fedora only. The support specifically aims to ensure trust in Firefox and Chromium-based browsers (Microsoft Edge, Chrome, and Chromium).
openssl tool must be on the path.certutil tool must be on the path.When an ASP.NET Core development certificate is trusted, the certificate is exported to a folder in the current user's home directory. To have OpenSSL (and clients that consume it) pick up this folder, you need to set the SSL_CERT_DIR environment variable. You can set the variable in a single session by running a command like export SSL_CERT_DIR=$HOME/.aspnet/dev-certs/trust:/usr/lib/ssl/certs (the exact value is in the output when --verbose is passed) or by adding it your (distro- and shell-specific) configuration file (for example .profile).
This approach is required to make tools like curl trust the development certificate. Alternatively, you can pass -CAfile or -CApath to each individual curl invocation.
Note
Requires 1.1.1h or later or 3.0.0 or later, depending on which major version you're using.
If OpenSSL trust gets into a bad state (for example if dotnet dev-certs https --clean fails to remove it), you can frequently resolve the situation by using the c_rehash tool.
If you're using another browser with its own Network Security Services (NSS) store, you can use the DOTNET_DEV_CERTS_NSSDB_PATHS environment variable to specify a colon-delimited list of NSS directories (for example, the directory containing cert9.db). You can then add the development certificate location to the list in the variable.
If you store the certificates you want OpenSSL to trust in a specific directory, you can use the DOTNET_DEV_CERTS_OPENSSL_CERTIFICATE_DIRECTORY environment variable to indicate the certificate location.
Warning
If you set either variable, be sure to set the same values each time trust is updated. If the values change, the tool doesn't know about certificates in the former locations (for example, during certificate cleanup).
As on other platforms, development certificates are stored and trusted separately for each user.
If you run dotnet dev-certs as a different user (for example, by using sudo), then that specific user (for example root) trusts the development certificate.
linux-dev-certs is an open-source, community-supported, .NET global tool that provides a convenient way to create and trust a developer certificate on Linux. Microsoft doesn't maintain or support the tool.
The following commands install the tool and create a trusted developer certificate:
dotnet tool update -g linux-dev-certs
dotnet linux-dev-certs install
For more information or to report issues, see the linux-dev-certs GitHub repository.
dotnet dev-certs https --trust isn't officially supported on SLES. Use the following steps to export the development certificate and trust it in Chromium-based browsers, Firefox, and command-line tools. The steps were verified on SLES 15 SP7 and openSUSE Leap 15.6.
Warning
The following instructions are intended for development purposes only. Don't use the development certificate in a production environment.
Note
Adding the certificate to the system trust store (/etc/pki/trust/anchors/ followed by update-ca-certificates) doesn't work for the development certificate. The certificate isn't a certificate authority (CA:FALSE), so p11-kit lists it as an anchor but doesn't include it in the generated bundles, and OpenSSL continues to reject it. Trust it per application as shown below instead.
The certutil tool used to manage browser certificate stores is provided by the mozilla-nss-tools package:
sudo zypper install mozilla-nss-tools openssl
Replace ${CertificateDirectory} with a directory outside your source repositories, for example $HOME/.aspnet/https:
mkdir -p ${CertificateDirectory}
dotnet dev-certs https -ep ${CertificateDirectory}/aspnetcore.crt --format PEM --no-password
certutil -d sql:$HOME/.pki/nssdb -A -t "P,," -n aspnetcore -i ${CertificateDirectory}/aspnetcore.crt
If $HOME/.pki/nssdb doesn't exist yet, create it first with certutil -d sql:$HOME/.pki/nssdb -N --empty-password. Restart the browser after importing.
Replace ${UserProfile} with the name of your Firefox profile directory (see about:profiles in Firefox):
certutil -d sql:$HOME/.mozilla/firefox/${UserProfile}/ -A -t "C,," -n aspnetcore -i ${CertificateDirectory}/aspnetcore.crt
Pass the exported certificate explicitly:
curl --cacert ${CertificateDirectory}/aspnetcore.crt https://localhost:5001
Alternatively, point SSL_CERT_DIR at a directory that contains the certificate as described in OpenSSL trust.
certutil -d sql:$HOME/.pki/nssdb -D -n aspnetcore
certutil -d sql:$HOME/.mozilla/firefox/${UserProfile}/ -D -n aspnetcore
rm ${CertificateDirectory}/aspnetcore.crt
dotnet dev-certs https --clean
dotnet dev-certs https --trust isn't officially supported on RHEL. The following steps mirror the SLES instructions, adapted for RHEL package names.
Warning
The following instructions are intended for development purposes only. Don't use the development certificate in a production environment.
Note
As on SLES, adding the certificate to the system trust store (/etc/pki/ca-trust/source/anchors/ followed by update-ca-trust) doesn't work for the development certificate. The certificate isn't a certificate authority (CA:FALSE), so trust it per application as shown below instead.
The certutil tool used to manage browser certificate stores is provided by the nss-tools package:
sudo dnf install nss-tools openssl
Replace ${CertificateDirectory} with a directory outside your source repositories, for example $HOME/.aspnet/https:
mkdir -p ${CertificateDirectory}
dotnet dev-certs https -ep ${CertificateDirectory}/aspnetcore.crt --format PEM --no-password
certutil -d sql:$HOME/.pki/nssdb -A -t "P,," -n aspnetcore -i ${CertificateDirectory}/aspnetcore.crt
If $HOME/.pki/nssdb doesn't exist yet, create it first with certutil -d sql:$HOME/.pki/nssdb -N --empty-password. Restart the browser after importing.
Replace ${UserProfile} with the name of your Firefox profile directory (see about:profiles in Firefox):
certutil -d sql:$HOME/.mozilla/firefox/${UserProfile}/ -A -t "C,," -n aspnetcore -i ${CertificateDirectory}/aspnetcore.crt
Pass the exported certificate explicitly:
curl --cacert ${CertificateDirectory}/aspnetcore.crt https://localhost:5001
Alternatively, create an OpenSSL hashed certificate directory and point SSL_CERT_DIR at it:
mkdir -p ${CertificateDirectory}/certs
cp ${CertificateDirectory}/aspnetcore.crt ${CertificateDirectory}/certs/
openssl rehash ${CertificateDirectory}/certs
export SSL_CERT_DIR=${CertificateDirectory}/certs
certutil -d sql:$HOME/.pki/nssdb -D -n aspnetcore
certutil -d sql:$HOME/.mozilla/firefox/${UserProfile}/ -D -n aspnetcore
rm ${CertificateDirectory}/aspnetcore.crt
dotnet dev-certs https --clean
Sometimes when an ASP.NET Core HTTPS development certificate is installed and trusted, the browser warns that the certificate is untrusted. The following sections provide help for troubleshooting this issue.
The ASP.NET Core HTTPS development certificate is used by Kestrel.
To repair the IIS Express certificate, see Stack Overflow issue #20036984 / answer #20048613 - How do I restore a missing IIS Express SSL Certificate?
For all platforms, try to resolve the untrusted certificate issues with the following steps:
Run the following commands:
dotnet dev-certs https --clean
dotnet dev-certs https --trust
Close any open browser instances, and open the app in a new browser window.
The browser cache stores whether a certificate is trusted. The close/open process helps to refresh the browser cache settings for certificates.
The dotnet dev-certs https commands usually solve most browser trust issues. If the dotnet dev-certs https --clean command fails and the browser still doesn't trust the certificate, try the platform-specific suggestions in the following sections.
If you're using Docker, try to resolve the issue with the following steps:
Delete the C:\Users{USER}\AppData\Roaming\ASP.NET\Https folder.
Clean the solution. Delete the bin and obj folders.
Restart the development tool. For example, Visual Studio or Visual Studio Code.
If you're working in Windows, complete the following troubleshooting steps:
Check the certificates in the certificate store. Look for a localhost certificate with the ASP.NET Core HTTPS development certificate friendly name in two folders:
Remove all certificates from both Personal and Trusted root certification authorities.
Important
Do not remove the IIS Express localhost certificate.
Run the following commands:
dotnet dev-certs https --clean
dotnet dev-certs https --trust
Close any open browser instances, and open the app in a new browser window.
If you're working with OS X, try to resolve the issue with the following steps:
Open KeyChain Access, and then select the System keychain.
Check for the presence of a localhost certificate.
Confirm the certificate shows the plus (+) symbol on the icon, which indicates the certificate is trusted for all users.
Remove the certificate from the system keychain.
Run the following commands:
dotnet dev-certs https --clean
dotnet dev-certs https --trust
Close any open browser instances, and open the app in a new browser window.
For more information about troubleshooting certificate issues with Visual Studio, see GitHub dotnet/aspnetcore issue #16892) - HTTPS Error using IIS Express.
If you're running Linux, follow these steps to troubleshoot the untrusted certificate:
Confirm the certificate you're investigating is the user HTTPS developer certificate planned for use by the Kestrel server.
Check the current user default HTTPS developer Kestrel certificate at the following location:
ls -la ~/.dotnet/corefx/cryptography/x509stores/my
The HTTPS developer Kestrel certificate file is the SHA1 thumbprint. When the file is deleted with the dotnet dev-certs https --clean command, the file is regenerated when needed with a different thumbprint.
Verify the thumbprint of the exported certificate matches by running the following command:
openssl x509 -noout -fingerprint -sha1 -inform pem -in /usr/local/share/ca-certificates/aspnet/https.crt
If the certificate thumbprint doesn't match, investigate the following conditions:
Check if the certificate is old.
Check if the certificate is an exported developer certificate for the root user.
Check the root user certificate in the following folder:
ls -la /root/.dotnet/corefx/cryptography/x509stores/my
To fix problems with the IIS Express certificate, select Repair in the Visual Studio installer. For more information, see GitHub dotnet/aspnetcore issue #16892) - HTTPS Error using IIS Express.
In some cases, group policy can prevent self-signed certificates from being trusted. For more information, see GitHub dotnet/aspnetcore issue #21173 - Error trusting HTTPS developer certificate.
Note
If you're using .NET 9 or later SDK, see the updated Linux procedures in the .NET 9 version of this article.
Warning
Do not use RequireHttpsAttribute on Web APIs that receive sensitive information. RequireHttpsAttribute uses HTTP status codes to redirect browsers from HTTP to HTTPS. API clients may not understand or obey redirects from HTTP to HTTPS. Such clients may send information over HTTP. Web APIs should either:
To disable HTTP redirection in an API, set the ASPNETCORE_URLS environment variable or use the --urls command line flag. For more information, see ASP.NET Core runtime environments and 8 ways to set the URLs for an ASP.NET Core app by Andrew Lock.
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. Even within browsers, a single authenticated call to an API over HTTP has risks on insecure networks. The secure approach is to configure API projects to only listen to and respond over HTTPS.
Requests to an endpoint using HTTP that are redirected to HTTPS by UseHttpsRedirection fail with ERR_INVALID_REDIRECT on the CORS preflight request.
API projects can reject HTTP requests rather than use UseHttpsRedirection to redirect requests to HTTPS.
We recommend that production ASP.NET Core web apps use:
Note
Apps deployed in a reverse proxy configuration allow the proxy to handle connection security (HTTPS). If the proxy also handles HTTPS redirection, there's no need to use HTTPS redirection middleware. 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. For more information, see Opt-out of HTTPS/HSTS on project creation.
UseHttpsRedirection)The following code calls UseHttpsRedirection in the Program.cs file:
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();
The preceding highlighted code:
ASPNETCORE_HTTPS_PORT environment variable or IServerAddressesFeature.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. We recommend using HSTS to signal to clients that only secure resource requests should be sent to the app (only in production).
A port must be available for the middleware to redirect an insecure request to HTTPS. If no port is available:
Specify the HTTPS port using any of the following approaches:
Set the https_port host setting:
In host configuration.
By setting the ASPNETCORE_HTTPS_PORT environment variable.
By adding a top-level entry in appsettings.json:
{
"https_port": 443,
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
Indicate a port with the secure scheme using the ASPNETCORE_URLS environment variable. The environment variable configures the server. The middleware indirectly discovers the HTTPS port via IServerAddressesFeature. This approach doesn't work in reverse proxy deployments.
The ASP.NET Core web templates set an HTTPS URL in Properties/launchsettings.json for both Kestrel and IIS Express. launchsettings.json is only used on the local machine.
Configure an HTTPS URL endpoint for a public-facing edge deployment of Kestrel server or HTTP.sys server. Only one HTTPS port is used by the app. The middleware discovers the port via IServerAddressesFeature.
Note
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.
When Kestrel or HTTP.sys is used as a public-facing edge server, Kestrel or HTTP.sys must be configured to listen on both:
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.
For more information, see Kestrel endpoint configuration or HTTP.sys web server implementation in ASP.NET Core.
Any firewall between the client and server must also have communication ports open for traffic.
If requests are forwarded in a reverse proxy configuration, use forwarded headers middleware before calling HTTPS redirection middleware. Forwarded headers middleware updates the Request.Scheme, using the X-Forwarded-Proto header. 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.
When deploying to Azure App Service, follow the guidance in Tutorial: Bind an existing custom SSL certificate to Azure Web Apps.
The following highlighted code calls AddHttpsRedirection to configure middleware options:
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();
Calling AddHttpsRedirection is only necessary to change the values of HttpsPort or RedirectStatusCode.
The preceding highlighted code:
RedirectStatusCode.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.
When configuring services in 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();
An alternative to using HTTPS redirection middleware (UseHttpsRedirection) is to use URL rewriting middleware (AddRedirectToHttps). AddRedirectToHttps can also set the status code and port when the redirect is executed. For more information, see URL rewriting middleware.
When redirecting to HTTPS without the requirement for additional redirect rules, we recommend using HTTPS redirection middleware (UseHttpsRedirection) described in this article.
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. When a browser that supports HSTS receives this header:
Because HSTS is enforced by the client, it has some limitations:
ASP.NET Core implements HSTS with the UseHsts extension method. The following code calls UseHsts when the app isn't in development mode:
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 isn't recommended in development because the HSTS settings are highly cacheable by browsers. By default, UseHsts excludes the local loopback address.
For production environments that are implementing HTTPS for the first time, set the initial HstsOptions.MaxAge to a small value using one of the TimeSpan methods. Set the value from hours to no more than a single day in case you need to revert the HTTPS infrastructure to HTTP. 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 highlighted code:
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 header. Preload isn't part of the RFC HSTS specification, but is supported by web browsers to preload HSTS sites on fresh install. For more information, see https://hstspreload.org/.max-age parameter of the Strict-Transport-Security header to 60 days. If not set, defaults to 30 days. For more information, see the max-age directive.example.com to the list of hosts to exclude.UseHsts excludes the following loopback hosts:
localhost : The IPv4 loopback address.127.0.0.1 : The IPv4 loopback address.[::1] : The IPv6 loopback address.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 apps that are generated from the templates in Visual Studio or from the dotnet new command enable HTTPS redirection and HSTS. For deployments that don't require these scenarios, you can opt-out of HTTPS/HSTS when the app is created from the template.
To opt-out of HTTPS/HSTS:
Uncheck the Configure for HTTPS checkbox.
[New ASP.NET Core Web Application dialog showing the Configure for HTTPS checkbox unselected.]
Use the --no-https option. For example
dotnet new webapp --no-https
For the Firefox browser, see the next section.
The .NET Core SDK includes an HTTPS development certificate. The certificate is installed as part of the first-run experience. For example, dotnet --info produces a variation of the following output:
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.
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. To trust the certificate, perform the one-time step to run the dotnet dev-certs tool:
dotnet dev-certs https --trust
The following command provides help on the dotnet dev-certs tool:
dotnet dev-certs https --help
Warning
Do not create a development certificate in an environment that will be redistributed, such as a container image or virtual machine. Doing so can lead to spoofing and elevation of privilege. To help prevent this, set the DOTNET_GENERATE_ASPNET_CERTIFICATE environment variable to false prior to calling the .NET CLI for the first time. This will skip the automatic generation of the ASP.NET Core development certificate during the CLI's first-run experience.
The Firefox browser uses its own certificate store, and therefore doesn't trust the IIS Express or Kestrel developer certificates.
There are two approaches to trusting the HTTPS certificate with Firefox, create a policy file or configure with the FireFox browser. Configuring with the browser creates the policy file, so the two approaches are equivalent.
Create a policy file (policies.json) at:
%PROGRAMFILES%\Mozilla Firefox\distribution\Firefox.app/Contents/Resources/distributionAdd the following JSON to the Firefox policy file:
{
"policies": {
"Certificates": {
"ImportEnterpriseRoots": true
}
}
}
The preceding policy file makes Firefox trust certificates from the trusted certificates in the Windows certificate store. The next section provides an alternative approach to create the preceding policy file by using the Firefox browser.
Set security.enterprise_roots.enabled = true using the following instructions:
about:config in the FireFox browser.security.enterprise_roots.enabled = trueFor more information, see Setting Up Certificate Authorities (CAs) in Firefox and the mozilla/policy-templates/README file.
See this GitHub issue.
Establishing trust is distribution and browser specific. The following sections provide instructions for some popular distributions and the Chromium browsers (Edge and Chrome) and for Firefox.
The following instructions don't work for some Ubuntu versions, such as 20.04. For more information, see GitHub issue dotnet/AspNetCore.Docs #23686.
Install OpenSSL 1.1.1h or later. See your distribution for instructions on how to update OpenSSL.
Run the following commands:
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
The preceding commands:
ca-certificates folder, using the current user's environment.-E flag exports the root user certificate, generating it if necessary. Each newly generated certificate has a different thumbprint. When running as root, sudo and -E are not needed.The path in the preceding command is specific for Ubuntu. For other distributions, select an appropriate path or use the path for the Certificate Authorities (CAs).
For chromium browsers on Linux:
Install the libnss3-tools for your distribution.
Create or verify the $HOME/.pki/nssdb folder exists on the machine.
Export the certificate with the following command:
dotnet dev-certs https
sudo -E dotnet dev-certs https -ep /usr/local/share/ca-certificates/aspnet/https.crt --format PEM
The path in the preceding command is specific for Ubuntu. For other distributions, select an appropriate path or use the path for the Certificate Authorities (CAs).
Run the following commands:
certutil -d sql:$HOME/.pki/nssdb -A -t "P,," -n localhost -i /usr/local/share/ca-certificates/aspnet/https.crt
Exit and restart the browser.
Export the certificate with the following command:
dotnet dev-certs https
sudo -E dotnet dev-certs https -ep /usr/local/share/ca-certificates/aspnet/https.crt --format PEM
The path in the preceding command is specific for Ubuntu. For other distributions, select an appropriate path or use the path for the Certificate Authorities (CAs).
Create a JSON file at /usr/lib/firefox/distribution/policies.json with the following command:
cat <<EOF | sudo tee /usr/lib/firefox/distribution/policies.json
{
"policies": {
"Certificates": {
"Install": [
"/usr/local/share/ca-certificates/aspnet/https.crt"
]
}
}
}
EOF
Note: Ubuntu 21.10 Firefox comes as a snap package and the installation folder is /snap/firefox/current/usr/lib/firefox.
See Configure trust of HTTPS certificate using Firefox browser in this article for an alternative way to configure the policy file using the browser.
Warning
The following instructions are intended for development purposes only. Do not use the certificates generated in these instructions for a production environment.
These instructions use Mozilla's legacy tool certutil at https://firefox-source-docs.mozilla.org/security/nss/legacy/tools/nss_tools_certutil/index.html. Instructions may be updated as modern utilities and practices are discovered.
Caution
Improper use of TLS certificates could lead to spoofing.
Tip
Instructions for valid production certificates can be found in the RHEL Documentation. RHEL8 TLS Certificates RHEL9 TLS Certificates RHEL9 Certificate System
dnf install nss-tools
Important
Replace ${ProjectDirectory} with your projects directory.
Replace ${CertificateName} with a name you'll be able to identify in the future.
cd ${ProjectDirectory}
dotnet dev-certs https -ep ${ProjectDirectory}/${CertificateName}.crt --format PEM
Caution
If using git, add your certificate to your ${ProjectDirectory}/.gitignore or ${ProjectDirectory}/.git/info/exclude.
View the git documentation for information about these files.
Tip
You can move your exported certificate outside of your Git repository and replace the occurrences of ${ProjectDirectory}, in the following instructions, with the new location.
Important
Replace ${UserProfile} with the profile you intend to use.
Do not replace $HOME, it is the environment variable to your user directory.
certutil -d sql:$HOME/.pki/nssdb -A -t "P,," -n ${CertificateName} -i ${ProjectDirectory}/${CertificateName}.crt
certutil -d sql:$HOME/.pki/nssdb -A -t "C,," -n ${CertificateName} -i ${ProjectDirectory}/${CertificateName}.crt
certutil -d sql:$HOME/.mozilla/firefox/${UserProfile}/ -A -t "P,," -n ${CertificateName} -i ${ProjectDirectory}/${CertificateName}.crt
certutil -d sql:$HOME/.mozilla/firefox/${UserProfile}/ -A -t "C,," -n ${CertificateName} -i ${ProjectDirectory}/${CertificateName}.crt
Important
Don't delete the exported certificate if you plan to test with curl.
You'll need to create an alias referencing it in your $SHELL's profile
alias curl="curl --cacert ${ProjectDirectory}/${CertificateName}.crt"
certutil -d sql:$HOME/.pki/nssdb -D -n ${CertificateName}
certutil -d sql:$HOME/.mozilla/firefox/${UserProfile}/ -D -n ${CertificateName}
rm ${ProjectDirectory}/${CertificateName}.crt
dotnet dev-certs https --clean
Note
Remove the curl alias you created earlier
See:
See this GitHub issue.
The following instructions don't work for some Linux distributions, such as Ubuntu 20.04. For more information, see GitHub issue dotnet/AspNetCore.Docs #23686.
The Windows Subsystem for Linux (WSL) generates an HTTPS self-signed development certificate, which by default isn't trusted in Windows. The easiest way to have Windows trust the WSL certificate, is to configure WSL to use the same certificate as Windows:
On Windows, export the developer certificate to a file:
dotnet dev-certs https -ep https.pfx -p $CREDENTIAL_PLACEHOLDER$ --trust
Where $CREDENTIAL_PLACEHOLDER$ is a password.
In a WSL window, import the exported certificate on the WSL instance:
dotnet dev-certs https --clean --import <<path-to-pfx>> --password $CREDENTIAL_PLACEHOLDER$
The preceding approach is a one time operation per certificate and per WSL distribution. It's easier than exporting the certificate over and over. If you update or regenerate the certificate on windows, you might need to run the preceding commands again.
This section provides help when the ASP.NET Core HTTPS development certificate has been installed and trusted, but you still have browser warnings that the certificate is not trusted. The ASP.NET Core HTTPS development certificate is used by Kestrel.
To repair the IIS Express certificate, see this Stackoverflow issue.
Run the following commands:
dotnet dev-certs https --clean
dotnet dev-certs https --trust
Close any browser instances open. Open a new browser window to app. Certificate trust is cached by browsers.
The preceding commands solve most browser trust issues. If the browser is still not trusting the certificate, follow the platform-specific suggestions that follow.
localhost certificate with the ASP.NET Core HTTPS development certificate friendly name both under Current User > Personal > Certificates and Current User > Trusted root certification authorities > Certificatesdotnet dev-certs https --clean
dotnet dev-certs https --trust
Close any browser instances open. Open a new browser window to app.
+ symbol on the icon to indicate it's trusted for all users.dotnet dev-certs https --clean
dotnet dev-certs https --trust
Close any browser instances open. Open a new browser window to app.
See HTTPS Error using IIS Express (dotnet/AspNetCore #16892) for troubleshooting certificate issues with Visual Studio.
Check that the certificate being configured for trust is the user HTTPS developer certificate that will be used by the Kestrel server.
Check the current user default HTTPS developer Kestrel certificate at the following location:
ls -la ~/.dotnet/corefx/cryptography/x509stores/my
The HTTPS developer Kestrel certificate file is the SHA1 thumbprint. When the file is deleted via dotnet dev-certs https --clean, it's regenerated when needed with a different thumbprint.
Check the thumbprint of the exported certificate matches with the following command:
openssl x509 -noout -fingerprint -sha1 -inform pem -in /usr/local/share/ca-certificates/aspnet/https.crt
If the certificate doesn't match, it could be one of the following:
The root user certificate can be checked at:
ls -la /root/.dotnet/corefx/cryptography/x509stores/my
To fix problems with the IIS Express certificate, select Repair from the Visual Studio installer. For more information, see this GitHub issue.
In some cases, group policy may prevent self-signed certificates from being trusted. For more information, see this GitHub issue.
Warning
Do not use RequireHttpsAttribute on Web APIs that receive sensitive information. RequireHttpsAttribute uses HTTP status codes to redirect browsers from HTTP to HTTPS. API clients may not understand or obey redirects from HTTP to HTTPS. Such clients may send information over HTTP. Web APIs should either:
To disable HTTP redirection in an API, set the ASPNETCORE_URLS environment variable or use the --urls command line flag. For more information, see ASP.NET Core runtime environments and 5 ways to set the URLs for an ASP.NET Core app by Andrew Lock.
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. Even within browsers, a single authenticated call to an API over HTTP has risks on insecure networks. The secure approach is to configure API projects to only listen to and respond over HTTPS.
We recommend that production ASP.NET Core web apps use:
Note
Apps deployed in a reverse proxy configuration allow the proxy to handle connection security (HTTPS). If the proxy also handles HTTPS redirection, there's no need to use HTTPS redirection middleware. 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. For more information, see Opt-out of HTTPS/HSTS on project creation.
The following code calls UseHttpsRedirection in the Startup class:
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();
});
}
The preceding highlighted code:
ASPNETCORE_HTTPS_PORT environment variable or IServerAddressesFeature.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. We recommend using HSTS to signal to clients that only secure resource requests should be sent to the app (only in production).
A port must be available for the middleware to redirect an insecure request to HTTPS. If no port is available:
Specify the HTTPS port using any of the following approaches:
Set the https_port host setting:
In host configuration.
By setting the ASPNETCORE_HTTPS_PORT environment variable.
By adding a top-level entry in appsettings.json:
{
"https_port": 443,
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
Indicate a port with the secure scheme using the ASPNETCORE_URLS environment variable. The environment variable configures the server. The middleware indirectly discovers the HTTPS port via IServerAddressesFeature. This approach doesn't work in reverse proxy deployments.
In development, set an HTTPS URL in launchsettings.json. Enable HTTPS when IIS Express is used.
Configure an HTTPS URL endpoint for a public-facing edge deployment of Kestrel server or HTTP.sys server. Only one HTTPS port is used by the app. The middleware discovers the port via IServerAddressesFeature.
Note
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.
When Kestrel or HTTP.sys is used as a public-facing edge server, Kestrel or HTTP.sys must be configured to listen on both:
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.
For more information, see Kestrel endpoint configuration or HTTP.sys web server implementation in ASP.NET Core.
Any firewall between the client and server must also have communication ports open for traffic.
If requests are forwarded in a reverse proxy configuration, use forwarded headers middleware before calling HTTPS redirection middleware. Forwarded headers middleware updates the Request.Scheme, using the X-Forwarded-Proto header. 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.
When deploying to Azure App Service, follow the guidance in Tutorial: Bind an existing custom SSL certificate to Azure Web Apps.
The following highlighted code calls AddHttpsRedirection to configure middleware options:
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;
});
}
Calling AddHttpsRedirection is only necessary to change the values of HttpsPort or RedirectStatusCode.
The preceding highlighted code:
RedirectStatusCode.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.
When configuring services in 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;
});
}
}
An alternative to using HTTPS redirection middleware (UseHttpsRedirection) is to use URL rewriting middleware (AddRedirectToHttps). AddRedirectToHttps can also set the status code and port when the redirect is executed. For more information, see URL rewriting middleware.
When redirecting to HTTPS without the requirement for additional redirect rules, we recommend using HTTPS redirection middleware (UseHttpsRedirection) described in this article.
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. When a browser that supports HSTS receives this header:
Because HSTS is enforced by the client, it has some limitations:
ASP.NET Core implements HSTS with the UseHsts extension method. The following code calls UseHsts when the app isn't in development mode:
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 isn't recommended in development because the HSTS settings are highly cacheable by browsers. By default, UseHsts excludes the local loopback address.
For production environments that are implementing HTTPS for the first time, set the initial HstsOptions.MaxAge to a small value using one of the TimeSpan methods. Set the value from hours to no more than a single day in case you need to revert the HTTPS infrastructure to HTTP. 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.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 header. Preload isn't part of the RFC HSTS specification, but is supported by web browsers to preload HSTS sites on fresh install. For more information, see https://hstspreload.org/.max-age parameter of the Strict-Transport-Security header to 60 days. If not set, defaults to 30 days. For more information, see the max-age directive.example.com to the list of hosts to exclude.UseHsts excludes the following loopback hosts:
localhost : The IPv4 loopback address.127.0.0.1 : The IPv4 loopback address.[::1] : The IPv6 loopback address.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 apps that are generated from the templates in Visual Studio or from the dotnet new command enable HTTPS redirection and HSTS. For deployments that don't require these scenarios, you can opt-out of HTTPS/HSTS when the app is created from the template.
To opt-out of HTTPS/HSTS:
Uncheck the Configure for HTTPS checkbox.
Use the --no-https option. For example
dotnet new webapp --no-https
For the Firefox browser, see the next section.
The .NET Core SDK includes an HTTPS development certificate. The certificate is installed as part of the first-run experience. For example, running dotnet new webapp for the first time produces a variation of the following output:
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
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. To trust the certificate, perform the one-time step to run the dotnet dev-certs tool:
dotnet dev-certs https --trust
The following command provides help on the dotnet dev-certs tool:
dotnet dev-certs https --help
Warning
Do not create a development certificate in an environment that will be redistributed, such as a container image or virtual machine. Doing so can lead to spoofing and elevation of privilege. To help prevent this, set the DOTNET_GENERATE_ASPNET_CERTIFICATE environment variable to false prior to calling the .NET CLI for the first time. This will skip the automatic generation of the ASP.NET Core development certificate during the CLI's first-run experience.
The Firefox browser uses its own certificate store, and therefore doesn't trust the IIS Express or Kestrel developer certificates.
There are two approaches to trusting the HTTPS certificate with Firefox, create a policy file or configure with the FireFox browser. Configuring with the browser creates the policy file, so the two approaches are equivalent.
Create a policy file (policies.json) at:
%PROGRAMFILES%\Mozilla Firefox\distribution\Firefox.app/Contents/Resources/distributionAdd the following JSON to the Firefox policy file:
{
"policies": {
"Certificates": {
"ImportEnterpriseRoots": true
}
}
}
The preceding policy file makes Firefox trust certificates from the trusted certificates in the Windows certificate store. The next section provides an alternative approach to create the preceding policy file by using the Firefox browser.
Set security.enterprise_roots.enabled = true using the following instructions:
about:config in the FireFox browser.security.enterprise_roots.enabled = true.For more information, see Setting Up Certificate Authorities (CAs) in Firefox and the mozilla/policy-templates/README file.
See this GitHub issue.
Establishing trust is distribution and browser specific. The following sections provide instructions for some popular distributions and the Chromium browsers (Edge and Chrome) and for Firefox.
Install OpenSSL 1.1.1h or later. See your distribution for instructions on how to update OpenSSL.
Run the following commands:
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
The preceding commands:
ca-certificates folder, using the current user's environment.-E flag to export the root user certificate, generating it if necessary. Each newly generated certificate has a different thumbprint. When running as root, sudo and -E are not needed.The path in the preceding command is specific for Ubuntu. For other distributions, select an appropriate path or use the path for the Certificate Authorities (CAs).
For chromium browsers on Linux:
Install the libnss3-tools for your distribution.
Create or verify the $HOME/.pki/nssdb folder exists on the machine.
Export the certificate with the following command:
dotnet dev-certs https
sudo -E dotnet dev-certs https -ep /usr/local/share/ca-certificates/aspnet/https.crt --format PEM
The path in the preceding command is specific for Ubuntu. For other distributions, select an appropriate path or use the path for the Certificate Authorities (CAs).
Run the following commands:
certutil -d sql:$HOME/.pki/nssdb -A -t "P,," -n localhost -i /usr/local/share/ca-certificates/aspnet/https.crt
Exit and restart the browser.
Export the certificate with the following command:
dotnet dev-certs https
sudo -E dotnet dev-certs https -ep /usr/local/share/ca-certificates/aspnet/https.crt --format PEM
The path in the preceding command is specific for Ubuntu. For other distributions, select an appropriate path or use the path for the Certificate Authorities (CAs).
Create a JSON file at /usr/lib/firefox/distribution/policies.json with the following contents:
cat <<EOF | sudo tee /usr/lib/firefox/distribution/policies.json
{
"policies": {
"Certificates": {
"Install": [
"/usr/local/share/ca-certificates/aspnet/https.crt"
]
}
}
}
EOF
See Configure trust of HTTPS certificate using Firefox browser in this article for an alternative way to configure the policy file using the browser.
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
sudo cp localhost.crt /etc/pki/tls/certs/localhost.pem
sudo update-ca-trust
rm localhost.crt
See this GitHub comment for more information.
See this GitHub issue.
The Windows Subsystem for Linux (WSL) generates an HTTPS self-signed development certificate. To configure the Windows certificate store to trust the WSL certificate:
Export the developer certificate to a file on Windows:
dotnet dev-certs https -ep C:\<<path-to-folder>>\aspnetcore.pfx -p $CREDENTIAL_PLACEHOLDER$
Where $CREDENTIAL_PLACEHOLDER$ is a password.
In a WSL window, import the exported certificate on the WSL instance:
dotnet dev-certs https --clean --import /mnt/c/<<path-to-folder>>/aspnetcore.pfx -p $CREDENTIAL_PLACEHOLDER$
The preceding approach is a one time operation per certificate and per WSL distribution. It's easier than exporting the certificate over and over. If you update or regenerate the certificate on windows, you might need to run the preceding commands again.
This section provides help when the ASP.NET Core HTTPS development certificate has been installed and trusted, but you still have browser warnings that the certificate is not trusted. The ASP.NET Core HTTPS development certificate is used by Kestrel.
To repair the IIS Express certificate, see this Stackoverflow issue.
Run the following commands:
dotnet dev-certs https --clean
dotnet dev-certs https --trust
Close any browser instances that are open. Open a new browser window to the app. Certificate trust is cached by browsers.
The preceding commands solve most browser trust issues. If the browser is still not trusting the certificate, follow the platform-specific suggestions that follow.
localhost certificate with the ASP.NET Core HTTPS development certificate friendly name both under Current User > Personal > Certificates and Current User > Trusted root certification authorities > Certificatesdotnet dev-certs https --clean
dotnet dev-certs https --trust
Close any browser instances that are open. Open a new browser window to the app. Certificate trust is cached by browsers.
+ symbol on the icon to indicate it's trusted for all users.dotnet dev-certs https --clean
dotnet dev-certs https --trust
Close any browser instances that are open. Open a new browser window to the app. Certificate trust is cached by browsers.
See HTTPS Error using IIS Express (dotnet/AspNetCore #16892) for troubleshooting certificate issues with Visual Studio.
Check that the certificate being configured for trust is the user HTTPS developer certificate that will be used by the Kestrel server.
Check the current user default HTTPS developer Kestrel certificate at the following location:
ls -la ~/.dotnet/corefx/cryptography/x509stores/my
The HTTPS developer Kestrel certificate file is the SHA1 thumbprint. When the file is deleted via dotnet dev-certs https --clean, it's regenerated when needed with a different thumbprint.
Check the thumbprint of the exported certificate matches with the following command:
openssl x509 -noout -fingerprint -sha1 -inform pem -in /usr/local/share/ca-certificates/aspnet/https.crt
If the certificate doesn't match, it could be one of the following:
The root user certificate can be checked at:
ls -la /root/.dotnet/corefx/cryptography/x509stores/my
To fix problems with the IIS Express certificate, select Repair from the Visual Studio installer. For more information, see this GitHub issue.
Note
If you're using .NET 9 or later SDK, see the updated Linux procedures in the .NET 9 version of this article.
Warning
Do not use RequireHttpsAttribute on Web APIs that receive sensitive information. RequireHttpsAttribute uses HTTP status codes to redirect browsers from HTTP to HTTPS. API clients may not understand or obey redirects from HTTP to HTTPS. Such clients may send information over HTTP. Web APIs should either:
To disable HTTP redirection in an API, set the ASPNETCORE_URLS environment variable or use the --urls command line flag. For more information, see ASP.NET Core runtime environments and 8 ways to set the URLs for an ASP.NET Core app by Andrew Lock.
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. Even within browsers, a single authenticated call to an API over HTTP has risks on insecure networks. The secure approach is to configure API projects to only listen to and respond over HTTPS.
Requests to an endpoint using HTTP that are redirected to HTTPS by UseHttpsRedirection fail with ERR_INVALID_REDIRECT on the CORS preflight request.
API projects can reject HTTP requests rather than use UseHttpsRedirection to redirect requests to HTTPS.
We recommend that production ASP.NET Core web apps use:
Note
Apps deployed in a reverse proxy configuration allow the proxy to handle connection security (HTTPS). If the proxy also handles HTTPS redirection, there's no need to use HTTPS redirection middleware. 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. For more information, see Opt-out of HTTPS/HSTS on project creation.
UseHttpsRedirection)The following code calls UseHttpsRedirection in the Program.cs file:
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();
The preceding highlighted code:
ASPNETCORE_HTTPS_PORT environment variable or IServerAddressesFeature.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. We recommend using HSTS to signal to clients that only secure resource requests should be sent to the app (only in production).
A port must be available for the middleware to redirect an insecure request to HTTPS. If no port is available:
Specify the HTTPS port using any of the following approaches:
Set the https_port host setting:
In host configuration.
By setting the ASPNETCORE_HTTPS_PORT environment variable.
By adding a top-level entry in appsettings.json:
{
"https_port": 443,
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
Indicate a port with the secure scheme using the ASPNETCORE_URLS environment variable. The environment variable configures the server. The middleware indirectly discovers the HTTPS port via IServerAddressesFeature. This approach doesn't work in reverse proxy deployments.
The ASP.NET Core web templates set an HTTPS URL in Properties/launchsettings.json for both Kestrel and IIS Express. launchsettings.json is only used on the local machine.
Configure an HTTPS URL endpoint for a public-facing edge deployment of Kestrel server or HTTP.sys server. Only one HTTPS port is used by the app. The middleware discovers the port via IServerAddressesFeature.
Note
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.
When Kestrel or HTTP.sys is used as a public-facing edge server, Kestrel or HTTP.sys must be configured to listen on both:
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.
For more information, see Kestrel endpoint configuration or HTTP.sys web server implementation in ASP.NET Core.
Any firewall between the client and server must also have communication ports open for traffic.
If requests are forwarded in a reverse proxy configuration, use forwarded headers middleware before calling HTTPS redirection middleware. Forwarded headers middleware updates the Request.Scheme, using the X-Forwarded-Proto header. 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.
When deploying to Azure App Service, follow the guidance in Tutorial: Bind an existing custom SSL certificate to Azure Web Apps.
The following highlighted code calls AddHttpsRedirection to configure middleware options:
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();
Calling AddHttpsRedirection is only necessary to change the values of HttpsPort or RedirectStatusCode.
The preceding highlighted code:
RedirectStatusCode.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.
When configuring services in 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();
An alternative to using HTTPS redirection middleware (UseHttpsRedirection) is to use URL rewriting middleware (AddRedirectToHttps). AddRedirectToHttps can also set the status code and port when the redirect is executed. For more information, see URL rewriting middleware.
When redirecting to HTTPS without the requirement for additional redirect rules, we recommend using HTTPS redirection middleware (UseHttpsRedirection) described in this article.
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. When a browser that supports HSTS receives this header:
Because HSTS is enforced by the client, it has some limitations:
ASP.NET Core implements HSTS with the UseHsts extension method. The following code calls UseHsts when the app isn't in development mode:
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 isn't recommended in development because the HSTS settings are highly cacheable by browsers. By default, UseHsts excludes the local loopback address.
For production environments that are implementing HTTPS for the first time, set the initial HstsOptions.MaxAge to a small value using one of the TimeSpan methods. Set the value from hours to no more than a single day in case you need to revert the HTTPS infrastructure to HTTP. 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 highlighted code:
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 header. Preload isn't part of the RFC HSTS specification, but is supported by web browsers to preload HSTS sites on fresh install. For more information, see https://hstspreload.org/.max-age parameter of the Strict-Transport-Security header to 60 days. If not set, defaults to 30 days. For more information, see the max-age directive.example.com to the list of hosts to exclude.UseHsts excludes the following loopback hosts:
localhost : The IPv4 loopback address.127.0.0.1 : The IPv4 loopback address.[::1] : The IPv6 loopback address.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 apps that are generated from the templates in Visual Studio or from the dotnet new command enable HTTPS redirection and HSTS. For deployments that don't require these scenarios, you can opt-out of HTTPS/HSTS when the app is created from the template.
To opt-out of HTTPS/HSTS:
Uncheck the Configure for HTTPS checkbox.
[New ASP.NET Core Web Application dialog showing the Configure for HTTPS checkbox unselected.]
Use the --no-https option. For example
dotnet new webapp --no-https
For the Firefox browser, see the next section.
The .NET Core SDK includes an HTTPS development certificate. The certificate is installed as part of the first-run experience. For example, dotnet --info produces a variation of the following output:
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.
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. To trust the certificate, perform the one-time step to run the dotnet dev-certs tool:
dotnet dev-certs https --trust
The following command provides help on the dotnet dev-certs tool:
dotnet dev-certs https --help
Warning
Do not create a development certificate in an environment that will be redistributed, such as a container image or virtual machine. Doing so can lead to spoofing and elevation of privilege. To help prevent this, set the DOTNET_GENERATE_ASPNET_CERTIFICATE environment variable to false prior to calling the .NET CLI for the first time. This will skip the automatic generation of the ASP.NET Core development certificate during the CLI's first-run experience.
The Firefox browser uses its own certificate store, and therefore doesn't trust the IIS Express or Kestrel developer certificates.
There are two approaches to trusting the HTTPS certificate with Firefox, create a policy file or configure with the FireFox browser. Configuring with the browser creates the policy file, so the two approaches are equivalent.
Create a policy file (policies.json) at:
%PROGRAMFILES%\Mozilla Firefox\distribution\Firefox.app/Contents/Resources/distributionAdd the following JSON to the Firefox policy file:
{
"policies": {
"Certificates": {
"ImportEnterpriseRoots": true
}
}
}
The preceding policy file makes Firefox trust certificates from the trusted certificates in the Windows certificate store. The next section provides an alternative approach to create the preceding policy file by using the Firefox browser.
Set security.enterprise_roots.enabled = true using the following instructions:
about:config in the FireFox browser.security.enterprise_roots.enabled = trueFor more information, see Setting Up Certificate Authorities (CAs) in Firefox and the mozilla/policy-templates/README file.
See this GitHub issue.
Establishing trust is distribution and browser specific. The following sections provide instructions for some popular distributions and the Chromium browsers (Edge and Chrome) and for Firefox.
The following instructions don't work for some Ubuntu versions, such as 20.04. For more information, see GitHub issue dotnet/AspNetCore.Docs #23686.
Install OpenSSL 1.1.1h or later. See your distribution for instructions on how to update OpenSSL.
Run the following commands:
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
The preceding commands:
ca-certificates folder, using the current user's environment.-E flag exports the root user certificate, generating it if necessary. Each newly generated certificate has a different thumbprint. When running as root, sudo and -E are not needed.The path in the preceding command is specific for Ubuntu. For other distributions, select an appropriate path or use the path for the Certificate Authorities (CAs).
For chromium browsers on Linux:
Install the libnss3-tools for your distribution.
Create or verify the $HOME/.pki/nssdb folder exists on the machine.
Export the certificate with the following command:
dotnet dev-certs https
sudo -E dotnet dev-certs https -ep /usr/local/share/ca-certificates/aspnet/https.crt --format PEM
The path in the preceding command is specific for Ubuntu. For other distributions, select an appropriate path or use the path for the Certificate Authorities (CAs).
Run the following commands:
certutil -d sql:$HOME/.pki/nssdb -A -t "P,," -n localhost -i /usr/local/share/ca-certificates/aspnet/https.crt
Exit and restart the browser.
Export the certificate with the following command:
dotnet dev-certs https
sudo -E dotnet dev-certs https -ep /usr/local/share/ca-certificates/aspnet/https.crt --format PEM
The path in the preceding command is specific for Ubuntu. For other distributions, select an appropriate path or use the path for the Certificate Authorities (CAs).
Create a JSON file at /usr/lib/firefox/distribution/policies.json with the following command:
cat <<EOF | sudo tee /usr/lib/firefox/distribution/policies.json
{
"policies": {
"Certificates": {
"Install": [
"/usr/local/share/ca-certificates/aspnet/https.crt"
]
}
}
}
EOF
Note: Ubuntu 21.10 Firefox comes as a snap package and the installation folder is /snap/firefox/current/usr/lib/firefox.
See Configure trust of HTTPS certificate using Firefox browser in this article for an alternative way to configure the policy file using the browser.
Warning
The following instructions are intended for development purposes only. Do not use the certificates generated in these instructions for a production environment.
These instructions use Mozilla's legacy tool certutil at https://firefox-source-docs.mozilla.org/security/nss/legacy/tools/nss_tools_certutil/index.html. Instructions may be updated as modern utilities and practices are discovered.
Caution
Improper use of TLS certificates could lead to spoofing.
Tip
Instructions for valid production certificates can be found in the RHEL Documentation. RHEL8 TLS Certificates RHEL9 TLS Certificates RHEL9 Certificate System
dnf install nss-tools
Important
Replace ${ProjectDirectory} with your projects directory.
Replace ${CertificateName} with a name you'll be able to identify in the future.
cd ${ProjectDirectory}
dotnet dev-certs https -ep ${ProjectDirectory}/${CertificateName}.crt --format PEM
Caution
If using git, add your certificate to your ${ProjectDirectory}/.gitignore or ${ProjectDirectory}/.git/info/exclude.
View the git documentation for information about these files.
Tip
You can move your exported certificate outside of your Git repository and replace the occurrences of ${ProjectDirectory}, in the following instructions, with the new location.
Important
Replace ${UserProfile} with the profile you intend to use.
Do not replace $HOME, it is the environment variable to your user directory.
certutil -d sql:$HOME/.pki/nssdb -A -t "P,," -n ${CertificateName} -i ${ProjectDirectory}/${CertificateName}.crt
certutil -d sql:$HOME/.pki/nssdb -A -t "C,," -n ${CertificateName} -i ${ProjectDirectory}/${CertificateName}.crt
certutil -d sql:$HOME/.mozilla/firefox/${UserProfile}/ -A -t "P,," -n ${CertificateName} -i ${ProjectDirectory}/${CertificateName}.crt
certutil -d sql:$HOME/.mozilla/firefox/${UserProfile}/ -A -t "C,," -n ${CertificateName} -i ${ProjectDirectory}/${CertificateName}.crt
Important
Don't delete the exported certificate if you plan to test with curl.
You'll need to create an alias referencing it in your $SHELL's profile
alias curl="curl --cacert ${ProjectDirectory}/${CertificateName}.crt"
certutil -d sql:$HOME/.pki/nssdb -D -n ${CertificateName}
certutil -d sql:$HOME/.mozilla/firefox/${UserProfile}/ -D -n ${CertificateName}
rm ${ProjectDirectory}/${CertificateName}.crt
dotnet dev-certs https --clean
Note
Remove the curl alias you created earlier
See:
See this GitHub issue.
The following instructions don't work for some Linux distributions, such as Ubuntu 20.04. For more information, see GitHub issue dotnet/AspNetCore.Docs #23686.
The Windows Subsystem for Linux (WSL) generates an HTTPS self-signed development certificate, which by default isn't trusted in Windows. The easiest way to have Windows trust the WSL certificate, is to configure WSL to use the same certificate as Windows:
On Windows, export the developer certificate to a file:
dotnet dev-certs https -ep https.pfx -p $CREDENTIAL_PLACEHOLDER$ --trust
Where $CREDENTIAL_PLACEHOLDER$ is a password.
In a WSL window, import the exported certificate on the WSL instance:
dotnet dev-certs https --clean --import <<path-to-pfx>> --password $CREDENTIAL_PLACEHOLDER$
The preceding approach is a one time operation per certificate and per WSL distribution. It's easier than exporting the certificate over and over. If you update or regenerate the certificate on windows, you might need to run the preceding commands again.
This section provides help when the ASP.NET Core HTTPS development certificate has been installed and trusted, but you still have browser warnings that the certificate is not trusted. The ASP.NET Core HTTPS development certificate is used by Kestrel.
To repair the IIS Express certificate, see this Stackoverflow issue.
Run the following commands:
dotnet dev-certs https --clean
dotnet dev-certs https --trust
Close any browser instances open. Open a new browser window to app. Certificate trust is cached by browsers.
The preceding commands solve most browser trust issues. If the browser is still not trusting the certificate, follow the platform-specific suggestions that follow.
localhost certificate with the ASP.NET Core HTTPS development certificate friendly name both under Current User > Personal > Certificates and Current User > Trusted root certification authorities > Certificatesdotnet dev-certs https --clean
dotnet dev-certs https --trust
Close any browser instances open. Open a new browser window to app.
+ symbol on the icon to indicate it's trusted for all users.dotnet dev-certs https --clean
dotnet dev-certs https --trust
Close any browser instances open. Open a new browser window to app.
See HTTPS Error using IIS Express (dotnet/AspNetCore #16892) for troubleshooting certificate issues with Visual Studio.
Check that the certificate being configured for trust is the user HTTPS developer certificate that will be used by the Kestrel server.
Check the current user default HTTPS developer Kestrel certificate at the following location:
ls -la ~/.dotnet/corefx/cryptography/x509stores/my
The HTTPS developer Kestrel certificate file is the SHA1 thumbprint. When the file is deleted via dotnet dev-certs https --clean, it's regenerated when needed with a different thumbprint.
Check the thumbprint of the exported certificate matches with the following command:
openssl x509 -noout -fingerprint -sha1 -inform pem -in /usr/local/share/ca-certificates/aspnet/https.crt
If the certificate doesn't match, it could be one of the following:
The root user certificate can be checked at:
ls -la /root/.dotnet/corefx/cryptography/x509stores/my
To fix problems with the IIS Express certificate, select Repair from the Visual Studio installer. For more information, see this GitHub issue.
In some cases, group policy may prevent self-signed certificates from being trusted. For more information, see this GitHub issue.
Note
If you're using .NET 9 or later SDK, see the updated Linux procedures in the .NET 9 version of this article.
Warning
Do not use RequireHttpsAttribute on Web APIs that receive sensitive information. RequireHttpsAttribute uses HTTP status codes to redirect browsers from HTTP to HTTPS. API clients may not understand or obey redirects from HTTP to HTTPS. Such clients may send information over HTTP. Web APIs should either:
To disable HTTP redirection in an API, set the ASPNETCORE_URLS environment variable or use the --urls command line flag. For more information, see ASP.NET Core runtime environments and 8 ways to set the URLs for an ASP.NET Core app by Andrew Lock.
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. Even within browsers, a single authenticated call to an API over HTTP has risks on insecure networks. The secure approach is to configure API projects to only listen to and respond over HTTPS.
Requests to an endpoint using HTTP that are redirected to HTTPS by UseHttpsRedirection fail with ERR_INVALID_REDIRECT on the CORS preflight request.
API projects can reject HTTP requests rather than use UseHttpsRedirection to redirect requests to HTTPS.
We recommend that production ASP.NET Core web apps use:
Note
Apps deployed in a reverse proxy configuration allow the proxy to handle connection security (HTTPS). If the proxy also handles HTTPS redirection, there's no need to use HTTPS redirection middleware. 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. For more information, see Opt-out of HTTPS/HSTS on project creation.
UseHttpsRedirection)The following code calls UseHttpsRedirection in the Program.cs file:
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();
The preceding highlighted code:
ASPNETCORE_HTTPS_PORT environment variable or IServerAddressesFeature.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. We recommend using HSTS to signal to clients that only secure resource requests should be sent to the app (only in production).
Note
Don't confuse the HTTPS_PORT configuration key and ASPNETCORE_HTTPS_PORT environment variable, which set the port for HTTPS redirection middleware, with the HTTPS_PORTS configuration key and ASPNETCORE_HTTPS_PORTS environment variable, which set the ports for Kestrel/HTTP.sys endpoint configuration.
A port must be available for the middleware to redirect an insecure request to HTTPS. If no port is available:
Specify the HTTPS port using any of the following approaches:
Set the https_port host setting:
In host configuration.
By setting the ASPNETCORE_HTTPS_PORT environment variable.
By adding a top-level entry in appsettings.json:
{
"https_port": 443,
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
Indicate a port with the secure scheme using the ASPNETCORE_URLS environment variable. The environment variable configures the server. The middleware indirectly discovers the HTTPS port via IServerAddressesFeature. This approach doesn't work in reverse proxy deployments.
The ASP.NET Core web templates set an HTTPS URL in Properties/launchsettings.json for both Kestrel and IIS Express. launchsettings.json is only used on the local machine.
Configure an HTTPS URL endpoint for a public-facing edge deployment of Kestrel server or HTTP.sys server. Only one HTTPS port is used by the app. The middleware discovers the port via IServerAddressesFeature.
Note
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.
When Kestrel or HTTP.sys is used as a public-facing edge server, Kestrel or HTTP.sys must be configured to listen on both:
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.
For more information, see Kestrel endpoint configuration or HTTP.sys web server implementation in ASP.NET Core.
Any firewall between the client and server must also have communication ports open for traffic.
If requests are forwarded in a reverse proxy configuration, use forwarded headers middleware before calling HTTPS redirection middleware. Forwarded headers middleware updates the Request.Scheme, using the X-Forwarded-Proto header. 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.
When deploying to Azure App Service, follow the guidance in Tutorial: Bind an existing custom SSL certificate to Azure Web Apps.
The following highlighted code calls AddHttpsRedirection to configure middleware options:
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();
Calling AddHttpsRedirection is only necessary to change the values of HttpsPort or RedirectStatusCode.
The preceding highlighted code:
RedirectStatusCode.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.
When configuring services in 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();
An alternative to using HTTPS redirection middleware (UseHttpsRedirection) is to use URL rewriting middleware (AddRedirectToHttps). AddRedirectToHttps can also set the status code and port when the redirect is executed. For more information, see URL rewriting middleware.
When redirecting to HTTPS without the requirement for additional redirect rules, we recommend using HTTPS redirection middleware (UseHttpsRedirection) described in this article.
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. When a browser that supports HSTS receives this header:
Because HSTS is enforced by the client, it has some limitations:
ASP.NET Core implements HSTS with the UseHsts extension method. The following code calls UseHsts when the app isn't in development mode:
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 isn't recommended in development because the HSTS settings are highly cacheable by browsers. By default, UseHsts excludes the local loopback address.
For production environments that are implementing HTTPS for the first time, set the initial HstsOptions.MaxAge to a small value using one of the TimeSpan methods. Set the value from hours to no more than a single day in case you need to revert the HTTPS infrastructure to HTTP. 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 highlighted code:
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 header. Preload isn't part of the RFC HSTS specification, but is supported by web browsers to preload HSTS sites on fresh install. For more information, see https://hstspreload.org/.max-age parameter of the Strict-Transport-Security header to 60 days. If not set, defaults to 30 days. For more information, see the max-age directive.example.com to the list of hosts to exclude.UseHsts excludes the following loopback hosts:
localhost : The IPv4 loopback address.127.0.0.1 : The IPv4 loopback address.[::1] : The IPv6 loopback address.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 apps that are generated from the templates in Visual Studio or from the dotnet new command enable HTTPS redirection and HSTS. For deployments that don't require these scenarios, you can opt-out of HTTPS/HSTS when the app is created from the template.
To opt-out of HTTPS/HSTS:
Uncheck the Configure for HTTPS checkbox.
[New ASP.NET Core Web Application dialog showing the Configure for HTTPS checkbox unselected.]
Use the --no-https option. For example
dotnet new webapp --no-https
For the Firefox browser, see the next section.
The .NET SDK includes an HTTPS development certificate. The certificate is installed as part of the first-run experience. For example, dotnet --info produces a variation of the following output:
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.
Installing the .NET 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. To trust the certificate, perform the one-time step to run the dotnet dev-certs tool:
dotnet dev-certs https --trust
The following command provides help on the dotnet dev-certs tool:
dotnet dev-certs https --help
Warning
Do not create a development certificate in an environment that will be redistributed, such as a container image or virtual machine. Doing so can lead to spoofing and elevation of privilege. To help prevent this, set the DOTNET_GENERATE_ASPNET_CERTIFICATE environment variable to false prior to calling the .NET CLI for the first time. This will skip the automatic generation of the ASP.NET Core development certificate during the CLI's first-run experience.
The Firefox browser uses its own certificate store, and therefore doesn't trust the IIS Express or Kestrel developer certificates.
There are two approaches to trusting the HTTPS certificate with Firefox, create a policy file or configure with the FireFox browser. Configuring with the browser creates the policy file, so the two approaches are equivalent.
Create a policy file (policies.json) at:
%PROGRAMFILES%\Mozilla Firefox\distribution\Firefox.app/Contents/Resources/distributionAdd the following JSON to the Firefox policy file:
{
"policies": {
"Certificates": {
"ImportEnterpriseRoots": true
}
}
}
The preceding policy file makes Firefox trust certificates from the trusted certificates in the Windows certificate store. The next section provides an alternative approach to create the preceding policy file by using the Firefox browser.
Set security.enterprise_roots.enabled = true using the following instructions:
about:config in the FireFox browser.security.enterprise_roots.enabled = trueFor more information, see Setting Up Certificate Authorities (CAs) in Firefox and the mozilla/policy-templates/README file.
See this GitHub issue.
Establishing trust is distribution and browser specific. The following sections provide instructions for some popular distributions and the Chromium browsers (Edge and Chrome) and for Firefox.
linux-dev-certs is an open-source, community-supported, .NET global tool that provides a convenient way to create and trust a developer certificate on Linux. The tool is not maintained or supported by Microsoft.
The following commands install the tool and create a trusted developer certificate:
dotnet tool update -g linux-dev-certs
dotnet linux-dev-certs install
For more information or to report issues, see the linux-dev-certs GitHub repository.
The following instructions don't work for some Ubuntu versions, such as 20.04. For more information, see GitHub issue dotnet/AspNetCore.Docs #23686.
Install OpenSSL 1.1.1h or later. See your distribution for instructions on how to update OpenSSL.
Run the following commands:
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
The preceding commands:
ca-certificates folder, using the current user's environment.-E flag exports the root user certificate, generating it if necessary. Each newly generated certificate has a different thumbprint. When running as root, sudo and -E are not needed.The path in the preceding command is specific for Ubuntu. For other distributions, select an appropriate path or use the path for the Certificate Authorities (CAs).
For chromium browsers on Linux:
Install the libnss3-tools for your distribution.
Create or verify the $HOME/.pki/nssdb folder exists on the machine.
Export the certificate with the following command:
dotnet dev-certs https
sudo -E dotnet dev-certs https -ep /usr/local/share/ca-certificates/aspnet/https.crt --format PEM
The path in the preceding command is specific for Ubuntu. For other distributions, select an appropriate path or use the path for the Certificate Authorities (CAs).
Run the following commands:
certutil -d sql:$HOME/.pki/nssdb -A -t "P,," -n localhost -i /usr/local/share/ca-certificates/aspnet/https.crt
Exit and restart the browser.
Export the certificate with the following command:
dotnet dev-certs https
sudo -E dotnet dev-certs https -ep /usr/local/share/ca-certificates/aspnet/https.crt --format PEM
The path in the preceding command is specific for Ubuntu. For other distributions, select an appropriate path or use the path for the Certificate Authorities (CAs).
Create a JSON file at /usr/lib/firefox/distribution/policies.json with the following command:
cat <<EOF | sudo tee /usr/lib/firefox/distribution/policies.json
{
"policies": {
"Certificates": {
"Install": [
"/usr/local/share/ca-certificates/aspnet/https.crt"
]
}
}
}
EOF
Note: Ubuntu 21.10 Firefox comes as a snap package and the installation folder is /snap/firefox/current/usr/lib/firefox.
See Configure trust of HTTPS certificate using Firefox browser in this article for an alternative way to configure the policy file using the browser.
Warning
The following instructions are intended for development purposes only. Do not use the certificates generated in these instructions for a production environment.
These instructions use Mozilla's legacy tool certutil at https://firefox-source-docs.mozilla.org/security/nss/legacy/tools/nss_tools_certutil/index.html. Instructions may be updated as modern utilities and practices are discovered.
Caution
Improper use of TLS certificates could lead to spoofing.
Tip
Instructions for valid production certificates can be found in the RHEL Documentation. RHEL8 TLS Certificates RHEL9 TLS Certificates RHEL9 Certificate System
dnf install nss-tools
Important
Replace ${ProjectDirectory} with your projects directory.
Replace ${CertificateName} with a name you'll be able to identify in the future.
cd ${ProjectDirectory}
dotnet dev-certs https -ep ${ProjectDirectory}/${CertificateName}.crt --format PEM
Caution
If using git, add your certificate to your ${ProjectDirectory}/.gitignore or ${ProjectDirectory}/.git/info/exclude.
View the git documentation for information about these files.
Tip
You can move your exported certificate outside of your Git repository and replace the occurrences of ${ProjectDirectory}, in the following instructions, with the new location.
Important
Replace ${UserProfile} with the profile you intend to use.
Do not replace $HOME, it is the environment variable to your user directory.
certutil -d sql:$HOME/.pki/nssdb -A -t "P,," -n ${CertificateName} -i ${ProjectDirectory}/${CertificateName}.crt
certutil -d sql:$HOME/.pki/nssdb -A -t "C,," -n ${CertificateName} -i ${ProjectDirectory}/${CertificateName}.crt
certutil -d sql:$HOME/.mozilla/firefox/${UserProfile}/ -A -t "P,," -n ${CertificateName} -i ${ProjectDirectory}/${CertificateName}.crt
certutil -d sql:$HOME/.mozilla/firefox/${UserProfile}/ -A -t "C,," -n ${CertificateName} -i ${ProjectDirectory}/${CertificateName}.crt
Important
Don't delete the exported certificate if you plan to test with curl.
You'll need to create an alias referencing it in your $SHELL's profile
alias curl="curl --cacert ${ProjectDirectory}/${CertificateName}.crt"
certutil -d sql:$HOME/.pki/nssdb -D -n ${CertificateName}
certutil -d sql:$HOME/.mozilla/firefox/${UserProfile}/ -D -n ${CertificateName}
rm ${ProjectDirectory}/${CertificateName}.crt
dotnet dev-certs https --clean
Note
Remove the curl alias you created earlier
See:
See this GitHub issue.
The following instructions don't work for some Linux distributions, such as Ubuntu 20.04. For more information, see GitHub issue dotnet/AspNetCore.Docs #23686.
The Windows Subsystem for Linux (WSL) generates an HTTPS self-signed development certificate, which by default isn't trusted in Windows. The easiest way to have Windows trust the WSL certificate, is to configure WSL to use the same certificate as Windows:
On Windows, export the developer certificate to a file:
dotnet dev-certs https -ep https.pfx -p $CREDENTIAL_PLACEHOLDER$ --trust
Where $CREDENTIAL_PLACEHOLDER$ is a password.
In a WSL window, import the exported certificate on the WSL instance:
dotnet dev-certs https --clean --import <<path-to-pfx>> --password $CREDENTIAL_PLACEHOLDER$
The preceding approach is a one time operation per certificate and per WSL distribution. It's easier than exporting the certificate over and over. If you update or regenerate the certificate on windows, you might need to run the preceding commands again.
This section provides help when the ASP.NET Core HTTPS development certificate has been installed and trusted, but you still have browser warnings that the certificate is not trusted. The ASP.NET Core HTTPS development certificate is used by Kestrel.
To repair the IIS Express certificate, see this Stackoverflow issue.
Run the following commands:
dotnet dev-certs https --clean
dotnet dev-certs https --trust
Close any browser instances open. Open a new browser window to app. Certificate trust is cached by browsers.
The preceding commands solve most browser trust issues. If the browser is still not trusting the certificate, follow the platform-specific suggestions that follow.
localhost certificate with the ASP.NET Core HTTPS development certificate friendly name both under Current User > Personal > Certificates and Current User > Trusted root certification authorities > Certificatesdotnet dev-certs https --clean
dotnet dev-certs https --trust
Close any browser instances open. Open a new browser window to app.
+ symbol on the icon to indicate it's trusted for all users.dotnet dev-certs https --clean
dotnet dev-certs https --trust
Close any browser instances open. Open a new browser window to app.
See HTTPS Error using IIS Express (dotnet/AspNetCore #16892) for troubleshooting certificate issues with Visual Studio.
Check that the certificate being configured for trust is the user HTTPS developer certificate that will be used by the Kestrel server.
Check the current user default HTTPS developer Kestrel certificate at the following location:
ls -la ~/.dotnet/corefx/cryptography/x509stores/my
The HTTPS developer Kestrel certificate file is the SHA1 thumbprint. When the file is deleted via dotnet dev-certs https --clean, it's regenerated when needed with a different thumbprint.
Check the thumbprint of the exported certificate matches with the following command:
openssl x509 -noout -fingerprint -sha1 -inform pem -in /usr/local/share/ca-certificates/aspnet/https.crt
If the certificate doesn't match, it could be one of the following:
The root user certificate can be checked at:
ls -la /root/.dotnet/corefx/cryptography/x509stores/my
To fix problems with the IIS Express certificate, select Repair from the Visual Studio installer. For more information, see this GitHub issue.
In some cases, group policy may prevent self-signed certificates from being trusted. For more information, see this GitHub issue.
Was this page helpful?
Was this page helpful?
Need help with this topic?
Want to try using Ask Learn to clarify or guide you through this topic?