Base solution for your next web application
Open Closed

SSL Error - OpenID Connect and Docker #5475


User avatar
0
tom.ohle created

Starting with a new 5.6.1 project (ASP.NET Core/Angular6), I enabled and configured OpenID Connect with Azure AD, spun up the app locally (visual studio 2017 debugger for back end; npm start for front end), and successfully authenticated by clicking the OpenID Connect icon on the login page.

Then I built the docker images and ran them, but now when I click the OpenID Connect icon I get this error.

System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.

Any idea why this error is only occurring when using Docker?

Here is the full stack trace.

System.InvalidOperationException: IDX20803: Unable to obtain configuration from: '[PII is hidden by default. Set the 'ShowPII' flag in IdentityModelEventSource.cs to true to reveal it.]'. ---> System.IO.IOException: IDX20804: Unable to retrieve document from: '[PII is hidden by default. Set the 'ShowPII' flag in IdentityModelEventSource.cs to true to reveal it.]'. ---> System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception. ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.
   at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, ExceptionDispatchInfo exception)
   at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.PartialFrameCallback(AsyncProtocolRequest asyncRequest)
--- End of stack trace from previous location where exception was thrown ---
   at System.Net.Security.SslState.ThrowIfExceptional()
   at System.Net.Security.SslState.InternalEndProcessAuthentication(LazyAsyncResult lazyResult)
   at System.Net.Security.SslState.EndProcessAuthentication(IAsyncResult result)
   at System.Net.Security.SslStream.EndAuthenticateAsClient(IAsyncResult asyncResult)
   at System.Net.Security.SslStream.<>c.<AuthenticateAsClientAsync>b__47_1(IAsyncResult iar)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask`1 creationTask)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
   at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel)
   --- End of inner exception stack trace ---
   at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel)
   at Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfigurationRetriever.GetAsync(String address, IDocumentRetriever retriever, CancellationToken cancel)
   at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)
   --- End of inner exception stack trace ---
   at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)
   at Abp.AspNetZeroCore.Web.Authentication.External.OpenIdConnect.OpenIdConnectAuthProviderApi.ValidateToken(String token, String issuer, IConfigurationManager`1 configurationManager, CancellationToken ct)
   at Abp.AspNetZeroCore.Web.Authentication.External.OpenIdConnect.OpenIdConnectAuthProviderApi.GetUserInfo(String token)
   at Stantec.DocView.Web.Controllers.TokenAuthController.GetExternalUserInfo(ExternalAuthenticateModel model)
   at Stantec.DocView.Web.Controllers.TokenAuthController.ExternalAuthenticate(ExternalAuthenticateModel model)
   at lambda_method(Closure , Object )
   at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextExceptionFilterAsync()

This seems to be the same issue: <a class="postlink" href="https://github.com/dotnet/corefx/issues/30313">https://github.com/dotnet/corefx/issues/30313</a>


3 Answer(s)
  • User Avatar
    0
    ismcagdas created
    Support Team

    @csegin, have you solved this problem ? Could it be a time difference problem ?

  • User Avatar
    0
    tom.ohle created

    I figured it out. Finally.

    I wrongly assumed that the OpenID Connect configuration document would be retrieved from...

    https://login.microsoftonline.com/<tenantid>/.well-known/openid-configuration
    

    ...when in fact it was coming from...

    https://sts.windows.net/<tenantid>/.well-known/openid-configuration
    

    ...instead.

    A quick curl from within the running host container revealed that a self-signed certificate was found in the certificate chain. This makes sense because our corporate network environment does some SSL interception. The docker container doesn't have this certificate by default, but my docker host OS (Windows 10) does. I browsed to the config url with Chrome and exported the root certificate from the certificate path as a 'Base-64 encoded X.509 (.CER)' file. I set the extension to 'crt', and edited the Host Dockerfile like so...

    FROM microsoft/dotnet:2.1-aspnetcore-runtime
    COPY RootCA.crt /usr/local/share/ca-certificates
    RUN update-ca-certificates
    ...
    

    Now the certificate is added to the container and the document can be retrieved.

  • User Avatar
    0
    ismcagdas created
    Support Team

    Great :)