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?