Updated sample to use new TLS Api (#39015)

This commit is contained in:
Leo 2021-12-14 16:33:40 -03:00 коммит произвёл GitHub
Родитель d18cb2e4b3
Коммит 5c21bfaa3c
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 31 добавлений и 13 удалений

Просмотреть файл

@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Server.Kestrel.Https;
using Microsoft.Extensions.Hosting;
@ -22,23 +24,39 @@ public class Program
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
// load the self-signed certificate issued for 127.0.0.1 and 127.0.0.2 domains
// https://docs.microsoft.com/en-us/dotnet/core/additional-tools/self-signed-certificates-guide
var serverCertificate = CertificateLoader.LoadFromStoreCert(
"localhost", "My", StoreLocation.CurrentUser,
allowInvalid: true);
webBuilder.UseStartup<Startup>();
webBuilder.ConfigureKestrel((context, options) =>
{
// Kestrel can't have different ssl settings for different hosts on the same IP because there's no way to change them based on SNI.
// https://github.com/dotnet/runtime/issues/31097
options.Listen(IPAddress.Parse(HostWithoutCert), 5001, listenOptions =>
options.ListenAnyIP(5001, listenOptions =>
{
listenOptions.UseHttps(httpsOptions =>
listenOptions.UseHttps(new TlsHandshakeCallbackOptions()
{
httpsOptions.ClientCertificateMode = ClientCertificateMode.NoCertificate;
});
});
options.Listen(IPAddress.Parse(HostWithCert), 5001, listenOptions =>
{
listenOptions.UseHttps(httpsOptions =>
{
httpsOptions.ClientCertificateMode = ClientCertificateMode.RequireCertificate;
OnConnection = connectionContext =>
{
// allow the tls connection without a client certificate
if (connectionContext.ClientHelloInfo.ServerName.Equals(HostWithoutCert, StringComparison.OrdinalIgnoreCase))
{
return new ValueTask<SslServerAuthenticationOptions>(new SslServerAuthenticationOptions()
{
ServerCertificate = serverCertificate,
ClientCertificateRequired = false
});
}
// require a client certificate to access 127.0.0.2
return new ValueTask<SslServerAuthenticationOptions>(new SslServerAuthenticationOptions()
{
ClientCertificateRequired = true,
ServerCertificate = serverCertificate,
RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => certificate is not null
});
}
});
});
});

Просмотреть файл

@ -9,4 +9,4 @@ There's an old way to renegotiate a connection if you find you need a client cer
This example shows an pattern for requiring client certificates only in some parts of your site by using different host bindings. The application is set up using two host names, mydomain.com and cert.mydomain.com (I've cheated and used 127.0.0.1 and 127.0.0.2 here instead to avoid setting up DNS). cert.mydomain.com is configured in the server to require client certificates, but mydomain.com is not. When you request part of the site that requires a client certificate it can redirect to the cert.mydomain.com while preserving the request path and query and the client will prompt for a certificate.
Redirecting back to mydomain.com does not accomplish a real sign-out because the browser still caches the client cert selected for cert.mydomain.com. The only way to clear the browser cache is to close the browser.
Redirecting back to mydomain.com does not accomplish a real sign-out because the browser still caches the client cert selected for cert.mydomain.com. The only way to clear the browser cache is to close the browser.