BearerAuthentication in Asp.Net Web Api 4.X

We are using Okta to secure our Asp.Net web api with Bearer Token. We could setup the app successfully as per Okta documentation. We host our production API in Azure as a web app service(We are suing PaaS). Everything is working as expected. But we run into an intermittent issue mainly when the API is not used for a couple of days.

Here is the issue: If we make a call to an end point that has [Authorize] attribute without token, we get UnAuthorize response as expected, but when we add a valid Bearer token into the header and make a call to the same end point, api will never response, it just hangs there till server return time-out error. After several investigations we realized this issue happens when the API is not used for a couple of days. When this happens, the only thing that can make the api responsive again is to restart the server.

Here is the code that we are using to verify the token in our OWIN startup class:

        private static void SetupOktaBearerAuthentication(IAppBuilder app)
    {
        TokenValidationParameters tvps = new TokenValidationParameters
        {
            //  Validate the JWT Audience (aud) claim
            ValidAudience = Config.Secured.ClientId,
            ValidateAudience = true,

            // Validate the JWT Issuer (iss) claim
            ValidIssuer = Config.Secured.OIdcIssuer,
            ValidateIssuer = true,

            // Validate the token expiry
            ValidateLifetime = true
        };

        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
        {
            AccessTokenFormat = new JwtFormat(tvps,
                new OpenIdConnectCachingSecurityTokenProvider(Config.Secured.OIdcIssuer + "/.well-known/openid-configuration"))
        });
    }

and here is the code for OpenIdConnectCachingSecurityTokenProvider

 public class OpenIdConnectCachingSecurityTokenProvider : IIssuerSecurityTokenProvider
{
    private readonly ConfigurationManager<OpenIdConnectConfiguration> _configManager;
    private string _issuer;
    private IEnumerable<SecurityToken> _tokens;
    private readonly ReaderWriterLockSlim _synclock = new ReaderWriterLockSlim();

    public OpenIdConnectCachingSecurityTokenProvider(string metadataEndpoint)
    {
        _configManager = new ConfigurationManager<OpenIdConnectConfiguration>(metadataEndpoint);
        RetrieveMetadata();
    }

    public string Issuer
    {
        get
        {
            RetrieveMetadata();
            _synclock.EnterReadLock();
            try
            {
                return _issuer;
            }
            finally
            {
                _synclock.ExitReadLock();
            }
        }
    }

    public IEnumerable<SecurityToken> SecurityTokens
    {
        get
        {
            RetrieveMetadata();
            _synclock.EnterReadLock();
            try
            {
                return _tokens;
            }
            finally
            {
                _synclock.ExitReadLock();
            }
        }
    }

    private void RetrieveMetadata()
    {
        _synclock.EnterWriteLock();
        try
        {
            var config = _configManager.GetConfigurationAsync().Result;
            _issuer = config.Issuer;
            _tokens = config.SigningTokens;
        }
        finally
        {
            _synclock.ExitWriteLock();
        }
    }
}

Can you please help us to solve this issue?

It might be this issue: https://github.com/oktadeveloper/okta-aspnet-mvc-example/issues/7

I updated the samples and documentation a few months ago to remove the possibility of this error. See the second half of this quickstart: Widget/JavaScript frontend + ASP.NET 4.x Web API backend

Can you try updating your OWIN startup code to appear more like the above?

That issue makes sense, I think we are running to the same problem. I changed the Token validation with the new code, hopefully we don’t get this error any more. What was the reason you used lock on previous method? Can we remove those locks?

@mohsenvafabio The old code was written before the OWIN 4.0 middleware was released, which now handles this automatically. :slight_smile:

Yep, you should definitely use the new OWIN middleware (as shown in the updated example) and get rid of any custom locking code you have. Let us know if you run into any problems.

@nate.barbettini Thanks, I just started using the Owin 4. we are deploying to production soon. I will let you know if we face the issue again.

Thanks for your help.

1 Like