This commit is contained in:
parent
818dc3b74a
commit
8b99354419
|
|
@ -301,6 +301,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https
|
|||
public Microsoft.AspNetCore.Server.Kestrel.Https.ClientCertificateMode ClientCertificateMode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
|
||||
public System.Func<System.Security.Cryptography.X509Certificates.X509Certificate2, System.Security.Cryptography.X509Certificates.X509Chain, System.Net.Security.SslPolicyErrors, bool> ClientCertificateValidation { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
|
||||
public System.TimeSpan HandshakeTimeout { get { throw null; } set { } }
|
||||
public System.Action<Microsoft.AspNetCore.Connections.ConnectionContext, System.Net.Security.SslServerAuthenticationOptions> OnAuthenticate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
|
||||
public System.Security.Cryptography.X509Certificates.X509Certificate2 ServerCertificate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
|
||||
public System.Func<Microsoft.AspNetCore.Connections.ConnectionContext, string, System.Security.Cryptography.X509Certificates.X509Certificate2> ServerCertificateSelector { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
|
||||
public System.Security.Authentication.SslProtocols SslProtocols { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
|
||||
|
|
|
|||
|
|
@ -75,6 +75,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https
|
|||
/// </summary>
|
||||
public bool CheckCertificateRevocation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Provides direct configuration of the <see cref="SslServerAuthenticationOptions"/> on a per-connection basis.
|
||||
/// This is called after all of the other settings have already been applied.
|
||||
/// </summary>
|
||||
public Action<ConnectionContext, SslServerAuthenticationOptions> OnAuthenticate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the maximum amount of time allowed for the TLS/SSL handshake. This must be positive and finite.
|
||||
/// </summary>
|
||||
|
|
@ -90,8 +96,5 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https
|
|||
_handshakeTimeout = value != Timeout.InfiniteTimeSpan ? value : TimeSpan.MaxValue;
|
||||
}
|
||||
}
|
||||
|
||||
// For testing
|
||||
internal Action OnHandshakeStarted;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,8 +127,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https.Internal
|
|||
var timeoutFeature = context.Features.Get<IConnectionTimeoutFeature>();
|
||||
timeoutFeature.SetTimeout(_options.HandshakeTimeout);
|
||||
|
||||
_options.OnHandshakeStarted?.Invoke();
|
||||
|
||||
try
|
||||
{
|
||||
// Adapt to the SslStream signature
|
||||
|
|
@ -170,6 +168,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https.Internal
|
|||
sslOptions.ApplicationProtocols.Add(SslApplicationProtocol.Http11);
|
||||
}
|
||||
|
||||
_options.OnAuthenticate?.Invoke(context.ConnectionContext, sslOptions);
|
||||
|
||||
await sslStream.AuthenticateAsServerAsync(sslOptions, CancellationToken.None);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
|
|
|
|||
|
|
@ -326,7 +326,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
listenOptions.UseHttps(o =>
|
||||
{
|
||||
o.ServerCertificate = new X509Certificate2(TestResources.GetTestCertificate());
|
||||
o.OnHandshakeStarted = () => handshakeStartedTcs.SetResult(null);
|
||||
o.OnAuthenticate = (_, __) => handshakeStartedTcs.SetResult(null);
|
||||
|
||||
handshakeTimeout = o.HandshakeTimeout;
|
||||
});
|
||||
|
|
@ -380,6 +380,81 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
Assert.Equal(LogLevel.Debug, loggerProvider.FilterLogger.LastLogLevel);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OnAuthenticate_SeesOtherSettings()
|
||||
{
|
||||
var loggerProvider = new HandshakeErrorLoggerProvider();
|
||||
LoggerFactory.AddProvider(loggerProvider);
|
||||
|
||||
var testCert = TestResources.GetTestCertificate();
|
||||
var onAuthenticateCalled = false;
|
||||
|
||||
await using (var server = new TestServer(context => Task.CompletedTask,
|
||||
new TestServiceContext(LoggerFactory),
|
||||
listenOptions =>
|
||||
{
|
||||
listenOptions.UseHttps(httpsOptions =>
|
||||
{
|
||||
httpsOptions.ServerCertificate = testCert;
|
||||
httpsOptions.OnAuthenticate = (connectionContext, authOptions) =>
|
||||
{
|
||||
Assert.Same(testCert, authOptions.ServerCertificate);
|
||||
onAuthenticateCalled = true;
|
||||
};
|
||||
});
|
||||
}))
|
||||
{
|
||||
using (var connection = server.CreateConnection())
|
||||
using (var sslStream = new SslStream(connection.Stream, true, (sender, certificate, chain, errors) => true))
|
||||
{
|
||||
await sslStream.AuthenticateAsClientAsync("127.0.0.1", clientCertificates: null,
|
||||
enabledSslProtocols: SslProtocols.None,
|
||||
checkCertificateRevocation: false);
|
||||
}
|
||||
}
|
||||
|
||||
Assert.True(onAuthenticateCalled, "onAuthenticateCalled");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OnAuthenticate_CanSetSettings()
|
||||
{
|
||||
var loggerProvider = new HandshakeErrorLoggerProvider();
|
||||
LoggerFactory.AddProvider(loggerProvider);
|
||||
|
||||
var testCert = TestResources.GetTestCertificate();
|
||||
var onAuthenticateCalled = false;
|
||||
|
||||
await using (var server = new TestServer(context => Task.CompletedTask,
|
||||
new TestServiceContext(LoggerFactory),
|
||||
listenOptions =>
|
||||
{
|
||||
listenOptions.UseHttps(httpsOptions =>
|
||||
{
|
||||
httpsOptions.ServerCertificateSelector = (_, __) => throw new NotImplementedException();
|
||||
httpsOptions.OnAuthenticate = (connectionContext, authOptions) =>
|
||||
{
|
||||
Assert.Null(authOptions.ServerCertificate);
|
||||
Assert.NotNull(authOptions.ServerCertificateSelectionCallback);
|
||||
authOptions.ServerCertificate = testCert;
|
||||
authOptions.ServerCertificateSelectionCallback = null;
|
||||
onAuthenticateCalled = true;
|
||||
};
|
||||
});
|
||||
}))
|
||||
{
|
||||
using (var connection = server.CreateConnection())
|
||||
using (var sslStream = new SslStream(connection.Stream, true, (sender, certificate, chain, errors) => true))
|
||||
{
|
||||
await sslStream.AuthenticateAsClientAsync("127.0.0.1", clientCertificates: null,
|
||||
enabledSslProtocols: SslProtocols.None,
|
||||
checkCertificateRevocation: false);
|
||||
}
|
||||
}
|
||||
|
||||
Assert.True(onAuthenticateCalled, "onAuthenticateCalled");
|
||||
}
|
||||
|
||||
private class HandshakeErrorLoggerProvider : ILoggerProvider
|
||||
{
|
||||
public HttpsConnectionFilterLogger FilterLogger { get; } = new HttpsConnectionFilterLogger();
|
||||
|
|
|
|||
Loading…
Reference in New Issue