Skip to content

Commit

Permalink
Improve handling of expired Access Token for Microsoft Purview
Browse files Browse the repository at this point in the history
Added additional logs to indicate when a token is used from cache, added or refreshed

Made sure that the absolute expiration of the token cache policy will be based on the current time and not the time the client object was created.
  • Loading branch information
wjohnson committed Dec 30, 2023
1 parent ad34bd1 commit 6f092e8
Showing 1 changed file with 26 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ public class PurviewClient
ILogger _logger;
private AppConfigurationSettings? config = new AppConfigurationSettings();
private MemoryCache _cache = MemoryCache.Default;
private CacheItemPolicy cacheItemPolicy;
private String TOKEN_CACHE_KEY = "token";
/// <summary>
/// Create Object passing the logger class
/// </summary>
Expand All @@ -524,10 +524,6 @@ public PurviewClient(ILogger logger)
_logger = logger;
httpclientManager = new HttpClientManager(logger);
this.PurviewclientHelper = new PurviewClientHelper(httpclientManager, logger);
cacheItemPolicy = new CacheItemPolicy
{
AbsoluteExpiration = DateTimeOffset.Now.AddHours(config!.tokenCacheTimeInHours)
};
}

/// <summary>
Expand Down Expand Up @@ -657,11 +653,20 @@ public async Task<EntityModel> search_entities(string QualifiedName)
}
private async Task<string> GetToken()
{

if (_cache.Contains("token"))
// If the Memory Cache already has a token stored
// test to see if it's actually expired (because the token might expire soon)
if (_cache.Contains(TOKEN_CACHE_KEY))
{
return ((AuthenticationResult)_cache.Get("token")).AccessToken;
var cachedAuth = (AuthenticationResult)_cache.Get(TOKEN_CACHE_KEY);
// If the cached auth expires later than NOW + 3 minutes
// We are good to use the token for the next operation
if (cachedAuth.ExpiresOn > DateTime.UtcNow.AddMinutes(3)){
_logger.LogInformation("PurviewClient-GetToken: Token cache hit, no need to refresh token");
return cachedAuth.AccessToken;
}
// Else, fall through and get a new token because it's about to expire
}
_logger.LogWarning("PurviewClient-GetToken: Purview Client Token doesn't exist or will expire soon, attempt refresh");

// Even if this is a console application here, a daemon application is a confidential client application
IConfidentialClientApplication app;
Expand Down Expand Up @@ -712,9 +717,19 @@ private async Task<string> GetToken()
return String.Empty;
}

//_token = result;
var cacheItem = new CacheItem("token", result);
_cache.Add(cacheItem, cacheItemPolicy);
_logger.LogInformation($"PurviewClient-GetToken: Purview Client Token refresh successful. Adding to cache and will expire in {config!.tokenCacheTimeInHours}");
var cacheItem = new CacheItem(TOKEN_CACHE_KEY, result);
// We need to recreate this CacheItemPolicy every time
// If we set the policy only once, the AbsoluteExpiration won't get updated
// This should only be a problem in long standing PurviewClient applications
var cacheItemPolicy = new CacheItemPolicy
{
AbsoluteExpiration = DateTimeOffset.Now.AddHours(config!.tokenCacheTimeInHours)
};
// Need to use Set in case the token already exists
// We expect that a token that expires in three minutes will be updated
// so the token will exist already
_cache.Set(cacheItem, cacheItemPolicy);
return result.AccessToken;
}
/// <summary>
Expand Down

0 comments on commit 6f092e8

Please sign in to comment.