TL;DR version (somewhat)
I've got two servers (X and Y) that are trying to communicate, but failing to do so over TLS1.2 (TLS1.1, and TLS1.0 both behave correctly).
I've got a server X that is failing to get a response from localhost
.
The call that is throwing an exception is this line of code
HttpResponseMessage response = await httpClient.GetAsync(address, cancel);
where address is https://localhost/XXXXX/Identity/.well-known/jwks
and cancel is IsCancellationRequested = false
I noticed that the server certificate being presented for https://localhost/XXXXX/Identity/.well-known/jwks
is one that is valid, signed with RSA256, not on a revocation list, etc etc, everything looks good, but the subject is *.testing.corp, which doesn't match the URL I am trying to navigate to. This causes a certificate warning when navigating to https://localhost/XXXXX/Identity/.well-known/jwks
from Chrome on server X, but after manually clicking through it I get the results I expect.
So my thought is that if I can override the cert validation of HttpClient.GetAsync, I should be able to make this work, so I add the following code around my client:
var handler = new WebRequestHandler();
httpClient = new HttpClient(handler);
handler.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(dumbvalidationdeletemeishouldnotbeversioned);
public static bool dumbvalidationdeletemeishouldnotbeversioned(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors err)
{
return true;
}
The interesting bit is that this never hits, when I step to the GetAsync
line of code, a step throws the exception without ever hitting the dummy validation.
What is going on? Why else could this method fail?
Even more context:
EDIT: Related, X is utilizing Identity Server to attempt to authenticate. The failure is occuring when trying to access https://localhost/XXXXX/Identity/.well-known/jwks
I am using IISCrypto to configure the protocols on these machines. (Taking @Oleg's advice in the comments did not change this behavior). I have configured them by clicking the "Best Practices" button and then un-checking TLS1.0 and TLS1.1, so that both servers look like this:
EDIT: Adding some stack trace information
Before I added my dummy handler, this is the thrown exception's stack trace:
System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send. ---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
--- End of inner exception stack trace ---
at System.Net.TlsStream.EndWrite(IAsyncResult asyncResult)
at System.Net.ConnectStream.WriteHeadersCallback(IAsyncResult ar)
--- End of inner exception stack trace ---
at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)
--- End of inner exception stack trace ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at XXXXXXXX.Authentication.Extensions.XXXXXXOpenIDConnectAuthentication.<ReadJWTKeys>d__8.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at XXXXXXX.Authentication.Extensions.XXXXXXOpenIDConnectAuthentication.<MessageRecieved>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Owin.Security.OpenIdConnect.OpenIdConnectAuthenticationHandler.<AuthenticateCoreAsync>d__1a.MoveNext()
After adding the dummy handler, the exception is completely null <-- see the comments. The exception is exactly the same, but the return statement in my dummy handler is never hit when I debug the process, so the crux of my question changes to "What else is there to check?"