title: ASP.NET Core Multiple JWTBearer authentication fails
body: <p>I have an ASP.NET Core 2.2 application running correctly using <code>JwtBearer</code> authentication configuration with Identity Server 4. All works fine until I wanted to have multiple authorities to be handled by the <code>[Authorize]</code> attribute.</p>
  <p>I went through multiple threads and issues about that and took a look at the documentation: <a href="https://docs.microsoft.com/en-us/aspnet/core/security/authorization/limitingidentitybyscheme?view=aspnetcore-2.2&amp;tabs=aspnetcore2x#use-multiple-authentication-schemes" rel="nofollow noreferrer">https://docs.microsoft.com/en-us/aspnet/core/security/authorization/limitingidentitybyscheme?view=aspnetcore-2.2&amp;tabs=aspnetcore2x#use-multiple-authentication-schemes</a> the exact same code does not work and produces the following failure:</p>
  <pre><code>fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
  An unhandled exception has occurred while executing the request.
  System.InvalidOperationException: IDX20803: Unable to obtain configuration from: '[PII is hidden]'. ---&gt; System.IO.IOException: IDX20804: Unable to retrieve document from: '[PII is hidden]'. ---&gt; System.Net.Http.HttpRequestException: No connection could be made because the target machine actively refused it ---&gt; System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it
  at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
  --- End of inner exception stack trace ---
  at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
  at System.Threading.Tasks.ValueTask1.get_Result() at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Threading.Tasks.ValueTask1.get_Result()
  at System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask1 creationTask) at System.Threading.Tasks.ValueTask1.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(Task1 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.ConfigurationManager1.GetConfigurationAsync(CancellationToken cancel)
  --- End of inner exception stack trace ---
  at Microsoft.IdentityModel.Protocols.ConfigurationManager1.GetConfigurationAsync(CancellationToken cancel) at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync() at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync() at Microsoft.AspNetCore.Authentication.AuthenticationHandler1.AuthenticateAsync()
  at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme)
  at Microsoft.AspNetCore.Authorization.Policy.PolicyEvaluator.AuthenticateAsync(AuthorizationPolicy policy, HttpContext context)
  at Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter.OnAuthorizationAsync(AuthorizationFilterContext context)
  at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
  at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
  at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
  at JQ.GrupoFontana.API.Startup.&lt;&gt;c.&lt;&lt;Configure&gt;b__9_1&gt;d.MoveNext() in C:\Users\carlostorrecillas\Documents\git\jq.grupofontana.api\JQ.GrupoFontana.API\Startup.cs:line 264
  --- End of stack trace from previous location where exception was thrown ---
  at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
  at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
  at Microsoft.AspNetCore.Cors.Infrastructure.CorsMiddleware.InvokeCore(HttpContext context)
  at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
  info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
  Request finished in 3073.2088ms 500 text/html; charset=utf-8
  </code></pre>
  <p>An example of the Authorization header is:</p>
  <pre><code>Authorization: Bearer …
  </code></pre>
  <p>Which is fine. The code in the API I have now is:</p>
  <pre><code>services.AddAuthentication(&quot;authority1&quot;)
              .AddJwtBearer(&quot;authority1&quot;, options =&gt;
              {
                  options.Authority = &quot;http://localhost:11710&quot;;
                  options.Audience = &quot;myaudience&quot;;
                  options.RequireHttpsMetadata = false;
                  options.Events = new JwtBearerEvents
                  {
                      OnMessageReceived = context =&gt;
                      {
                          if (context.Request.Path.Value.StartsWith(&quot;/hub&quot;, StringComparison.InvariantCultureIgnoreCase))
                          {
                              context.Token = context.Request.Query[&quot;access_token&quot;];
                          }
  
                          return Task.CompletedTask;
                      },
                      OnTokenValidated = context =&gt;
                      {
                          return Task.CompletedTask;
                      },
                      OnAuthenticationFailed = context =&gt;
                      {
                          return Task.CompletedTask;
                      },
                      OnChallenge = context =&gt;
                      {
                          return Task.CompletedTask;
                      }
                  };
              })
              .AddJwtBearer(&quot;authority2&quot;, options =&gt;
              {
                  options.Authority = &quot;http://localhost:11910&quot;;
                  options.Audience = &quot;myaudience&quot;;
                  options.RequireHttpsMetadata = false;
                  options.Events = new JwtBearerEvents
                  {
                      OnMessageReceived = context =&gt;
                      {
                          if (context.Request.Path.Value.StartsWith(&quot;/hub&quot;, StringComparison.InvariantCultureIgnoreCase))
                          {
                              context.Token = context.Request.Query[&quot;access_token&quot;];
                          }
  
                          return Task.CompletedTask;
                      },
                      OnTokenValidated = context =&gt;
                      {
                          return Task.CompletedTask;
                      },
                      OnAuthenticationFailed = context =&gt;
                      {
                          return Task.CompletedTask;
                      },
                      OnChallenge = context =&gt;
                      {
                          return Task.CompletedTask;
                      }
                  };
              });
  
              services.AddAuthorization(options =&gt;
              {
                  options.DefaultPolicy = new AuthorizationPolicyBuilder(&quot;authority1&quot;, &quot;authority2&quot;).RequireAuthenticatedUser()
                                                                                      .Build();
              });
  </code></pre>
  <p>You can ignore the <code>/hub</code> check stuff as that's to deal with tokens and SignalR. I added myself a breakpoint to each of the events just to see where is failing and the sequence is (note that <code>authority1</code> is the application running and <code>authority2</code> is currently stopped):</p>
  <pre><code>authority1.onMessageReceived - OK
  authority1.onTokenValidated - OK
  authority2.onMessageReceived - OK
  authority2.onAuthenticationFailed - Method completes then I get the exception
  </code></pre>
  <p>I'm not sure if the problem is that I need to have all authorities running for some sort of validation/communication (I wouldn't have thought so) or whether there is an actual bug in the ASP.NET code itself - which hey, that could also be the case. I'm not sure if I miss any other configuration from the API point of view but I would say it's all set.</p>
  <p>I'm using the standard <code>[Authorize]</code> attribute in my controllers without any authenticationschemes stuff in there - I have tried and that didn't work either.</p>
  <p>If any of you has come across this issue I would really appreciate some help.</p>
  <p>Many thanks!</p>
  <p><strong>UPDATE:</strong></p>
  <p>After a little bit more digging I could see this workaround:</p>
  <p><a href="https://github.com/aspnet/Security/issues/1680#issuecomment-370416251" rel="nofollow noreferrer">https://github.com/aspnet/Security/issues/1680#issuecomment-370416251</a></p>
  <p>setting the <code>context.NoResult()</code> on the OnAuthenticationFailed but I'm not sure if that's a valid configuration?</p>