ASP.NET Web API JWT intermittent 401 errors

时间:2019-04-16 22:55:53

标签: c# asp.net asp.net-web-api jwt

I am occasionally getting 401 errors when using JwtBearerAuthentication in Web API with a valid token. It seems to work fine most of the time, but once in a while it will start trowing 401 for no reason. I can use postman with the exact same token right after it gives me the error and it works fine.

It seems like once it starts giving the 401s they continue to occur more and more frequently until the application is unusable. I then recycle the app pool and it seems to clear back up for a while. The memory usage doesn't seem to be out of hand, so I don't think its a memory leak.

Here is the configuration in the startup


    var configurationManager = new ConfigurationManager<OpenIdConnectConfiguration>(
        authority + "/.well-known/openid-configuration",
        new OpenIdConnectConfigurationRetriever(),
        new HttpDocumentRetriever());

    app.UseJwtBearerAuthentication(new JwtBearerAuthenticationOptions
    {
        AuthenticationMode = AuthenticationMode.Active,
        TokenValidationParameters = new TokenValidationParameters
        {
            ValidAudience = "AUDIENCE",
            ValidIssuer = authority,
            IssuerSigningKeyResolver = (token, securityToken, identifier, parameters) =>
            {
                var discoveryDocument = Task.Run(() => configurationManager.GetConfigurationAsync()).GetAwaiter().GetResult();
                return discoveryDocument.SigningKeys;
            }
        }
    });

Here are the relevant packages


    <packages> 
      <package id="Microsoft.IdentityModel.JsonWebTokens" version="5.3.0" targetFramework="net462" /> 
      <package id="Microsoft.IdentityModel.Logging" version="5.3.0" targetFramework="net462" /> 
      <package id="Microsoft.IdentityModel.Protocols" version="5.3.0" targetFramework="net462" /> 
      <package id="Microsoft.IdentityModel.Protocols.OpenIdConnect" version="5.3.0" targetFramework="net462" /> 
      <package id="Microsoft.IdentityModel.Tokens" version="5.3.0" targetFramework="net462" /> 
      <package id="Microsoft.Owin" version="4.0.0" targetFramework="net462" /> 
      <package id="Microsoft.Owin.Host.SystemWeb" version="4.0.0" targetFramework="net462" /> 
      <package id="Microsoft.Owin.Security" version="4.0.0" targetFramework="net462" /> 
      <package id="Microsoft.Owin.Security.Jwt" version="4.0.0" targetFramework="net462" /> 
      <package id="Microsoft.Owin.Security.OAuth" version="4.0.0" targetFramework="net462" /> 
      <package id="System.IdentityModel.Tokens.Jwt" version="5.3.0" targetFramework="net462" /> 
    </packages>

I built the app using this tutorial

Has any one seen anything like this before?

1 个答案:

答案 0 :(得分:1)

There is very little information to find the possible cause. However, we can consider one thing, the delegate itself is a synchronous block but you are calling an async method with a awaiter on the same context. This is highly likely to be blocked by a deadlock.

var discoveryDocument = Task.Run(() => configurationManager.GetConfigurationAsync()).GetAwaiter().GetResult();

instead convert the code to this one -

var discoveryDocument = configurationManager.GetConfigurationAsync().ConfigureAwait(false).GetAwaiter().GetResult();

You can read about it in this blog post - https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html

Not sure if this is causing the issue. A possible hypothesis could be that this code is causing a deadlock and you might be running out of threads in pool and as a side effect 401 are increasing over time.

I would recommend running a memory profiler to see if this really is causing a deadlock.

Let me know if these fixes the issue.