Identityserver4: Token handler not found and remote certificate is invalid?

Created on 8 Mar 2017  路  6Comments  路  Source: IdentityServer/IdentityServer4

Hi,

Im using IdentityServer4 to handle login between a winform client and a selfhosted WCF service. I have setup the IdentityServer to be able to use 3 diffrent ways to communicate like this :

 if (identitySettings.EnableStandardPort)
            {
                host = new WebHostBuilder()
                        .UseConsul(cService, settingsService, MyServices.IdentityServer, address, identitySettings.StandardListenPort)
                        .UseKestrel()
                        .UseContentRoot(Directory.GetCurrentDirectory())
                        .UseUrls($"http://{address}:{identitySettings.StandardListenPort}")
                        .UseStartup<Startup>()
                        .Build();

                if ((envSettings.SmartCardSSLConnection?.Enabled == true && SmartCardSLLConnectionCert != null) || 
                    (envSettings.UsernamePasswordSSLConnection?.Enabled == true && UsernamePasswordSLLConnectionCert != null))
                    Task.Run(() => { host.Run(); });
                else
                    host.Run();
            }

            if (envSettings.SmartCardSSLConnection?.Enabled == true && SmartCardSLLConnectionCert != null)
            {
                host = new WebHostBuilder()
                        .UseConsul(cService, settingsService, MyServices.IdentityServer_SmartCard, address, identitySettings.SmartCardSSLPort)
                        .UseKestrel(options =>
                        {
                            HttpsConnectionFilterOptions httpsoptions = new HttpsConnectionFilterOptions();
                            httpsoptions.ServerCertificate = SmartCardSLLConnectionCert;
                            httpsoptions.ClientCertificateMode = envSettings.SmartCardSSLConnection.RequireClientCertificate ? ClientCertificateMode.RequireCertificate : ClientCertificateMode.NoCertificate;
                            httpsoptions.CheckCertificateRevocation = false;
                            options.UseHttps(httpsoptions);
                        })
                        .UseContentRoot(Directory.GetCurrentDirectory())
                        .UseUrls($"https://{address}:{identitySettings.SmartCardSSLPort}")
                        .UseStartup<Startup>()
                        .Build();

                if (envSettings.UsernamePasswordSSLConnection?.Enabled == true && UsernamePasswordSLLConnectionCert != null)
                    Task.Run(() => { host.Run(); });
                else
                    host.Run();
            }

            if (envSettings.UsernamePasswordSSLConnection?.Enabled == true && UsernamePasswordSLLConnectionCert != null)
            {

                host = new WebHostBuilder()
                        .UseConsul(cService, settingsService, MyServices.IdentityServer_SSL, address, identitySettings.UsernamePasswordSSLPort)
                        .UseKestrel(options =>
                        {
                            HttpsConnectionFilterOptions httpsoptions = new HttpsConnectionFilterOptions();
                            httpsoptions.ServerCertificate = UsernamePasswordSLLConnectionCert;
                            httpsoptions.ClientCertificateMode = envSettings.UsernamePasswordSSLConnection.RequireClientCertificate ? ClientCertificateMode.RequireCertificate : ClientCertificateMode.NoCertificate;
                            httpsoptions.CheckCertificateRevocation = false;
                            options.UseHttps(httpsoptions);
                        })


                        .UseContentRoot(Directory.GetCurrentDirectory())
                        .UseUrls($"https://{address}:{identitySettings.UsernamePasswordSSLPort}")
                        .UseStartup<Startup>()
                        .Build();
                host.Run();
            }
  1. Username and Password - Regular HTTP communication without certificate.
  2. Smartcard - Https communication with both client and service certificate.
  3. Username and Password Secure - Https communication with certificate

On the service I got this code to check the tooken :

if (environmentSettings.UsernamePasswordSSLConnection.Enabled || environmentSettings.SmartCardSSLConnection.Enabled)
            {
                if(environmentSettings.UsernamePasswordSSLConnection.Enabled)
                    result = await _consulService.GetService(MyServices.IdentityServer_SSL);
                else
                    result = await _consulService.GetService(MyServices.IdentityServer_SmartCard);

                endpoint = $"https://{result.Address}:{result.Port}/connect/introspect";
            }
            else
            {
                result = await _consulService.GetService(MyServices.IdentityServer);
                endpoint = $"http://{result.Address}:{result.Port}/connect/introspect";
            }

            IntrospectionClient ic = new IntrospectionClient(endpoint);
            //Todo refresh token if required?
            var res = await ic.SendAsync(new IntrospectionRequest { Token = token, ClientId = "my.wcf", ClientSecret = "secret.my.wcf" });
            return res;

The unsecure and secure username and password works great, the smartcard is not. Its no problem to get the tooken from the client but when the Introspection on the service is used I get the following exception from IdentityServer :

fail: Microsoft.AspNetCore.Server.Kestrel[0]
ConnectionFilter.OnConnection
System.AggregateException: One or more errors occurred. ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.
at System.Net.Security.SslState.InternalEndProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.Security.SslState.EndProcessAuthentication(IAsyncResult result)
at System.Threading.Tasks.TaskFactory1.FromAsyncCoreLogic(IAsyncResult iar, Func2 endFunction, Action1 endAction, Task1 promise, Boolean requiresSynchronization)
--- 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.AspNetCore.Server.Kestrel.Https.HttpsConnectionFilter.d__6.MoveNext()
--- End of inner exception stack trace ---
---> (Inner Exception #0) System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.
at System.Net.Security.SslState.InternalEndProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.Security.SslState.EndProcessAuthentication(IAsyncResult result)
at System.Threading.Tasks.TaskFactory1.FromAsyncCoreLogic(IAsyncResult iar, Func2 endFunction, Action1 endAction, Task1 promise, Boolean requiresSynchronization)
--- 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.AspNetCore.Server.Kestrel.Https.HttpsConnectionFilter.d__6.MoveNext()<---

I don麓t want to use a client certificate between the WCF service and the IdentityService so instead I try the Introspection for the secure username and password instead and this throws this exception :

fail: IdentityServer4.Validation.TokenValidator[0]
Token handle not found in token handle store.
{
"ValidateLifetime": true,
"AccessTokenType": "Reference",
"TokenHandle": "07459beb6904494a6eb0f58a887bb431a7de5c21e38e71be5ecf99734c80859a"
}

I thought that the tooken should be able to be checked with any URL?

How do I solve this without setting a certificate for the WCF service?

question

All 6 comments

Don't know the role of Konsul here - but you are not supposed to tweak the HTTPS settings of Kestrel directly (at least not in production).

It's the job of the proxy in front of Kestrel to deal with HTTPS

Do you mean that I should not do UseKestrel(Options => HTTPS settings?

In this case I dont have anything on the outside of the services, most of them are selfhosts installed as Windows Services.

This is not allowed with Kestrel. Use WebListener instead then.

The application is internal network only and if i read the documents correctly it is okay to use Kestrel on its own without proxy, and i believe the https settings follows the samples for the different certificate types.(except we allow some errors in dev that we don麓t allow in production)

For internal network scenarios, Kestrel is generally recommended for best performance, but in some scenarios you might want to use a feature that only WebListener offers.

Do you think the problem is related to Kestrel? It does state HTTPS support. I thought it might be the in memory store that maybe didn't support sharing between different endpoints.

We麓ll try a quick run with weblistener to see if it works.

You can close this issue.
There where multiple operational stores which gave these errors. Now everything works.

Thanks.

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings