-
Notifications
You must be signed in to change notification settings - Fork 388
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OAK-10780: add azure access token refresh logic #1441
Conversation
public void run() { | ||
try { | ||
log.debug("Checking for azure access token expiry at: {}", LocalDateTime.now()); | ||
OffsetDateTime tokenExpiryThreshold = OffsetDateTime.now().plusMinutes(5); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OffsetDateTime tokenExpiryThreshold = OffsetDateTime.now().plusMinutes(5); | |
OffsetDateTime tokenExpiryThreshold = OffsetDateTime.now().plusMinutes(20); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
azure identity serves the token from cache, and will only refresh the token when there are 5 minutes left in token expiry. so keeping a 20 minutes threshold will not help as the token will be served from cache only and will not be refreshed. hence i have taken a threshold of 5 minutes similar to what is being used in azure identity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no cache in IdentityClient.authenticateWithClientSecret.
So the token will definitely be refreshed even at 20 minutes.
With 5 minutes there is a risk of a single transient failure causing token expiration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess you are referring to an older version of azure identity.
we are using azure-identity@1.11.3. The token is first looked up in cache, and after the cache miss, a new token is generated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the clarification. In this case we should reduce the TOKEN_REFRESHER_DELAY to 1 minute so that even in the case of transient failures we will still successfully refresh before the token expires.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alternatively instead of ClientSecretCredential, you can create directly a ConfidentialClientApplication and set skipCache(true) in the parameters
// configure once, then store these for later use in the tokenrefresher:
ConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplication
.builder(clientId, ClientCredentialFactory.createFromSecret(clientSecret))
.authority("https://login.microsoftonline.com/" + tenantId + "/")
.build();
ClientCredentialParameters clientCredentialParameters =
ClientCredentialParameters.builder(Collections.singleton(AZURE_DEFAULT_SCOPE)).skipCache(true)
.tenant(IdentityUtil
.resolveTenantId(tenantId, new TokenRequestContext().addScopes(AZURE_DEFAULT_SCOPE), new IdentityClientOptions())).build();
// refreshing anytime:
IAuthenticationResult authResult = confidentialClientApplication.acquireToken(clientCredentialParameters).join();
AccessToken accessToken = new AccessToken(authResult.accessToken(), OffsetDateTime.ofInstant(authResult.expiresOnDate().toInstant(), ZoneOffset.UTC));
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer the first way here since that is tested. Reduced the token refresh interval to 1 minute
log.debug("Checking for azure access token expiry at: {}", LocalDateTime.now()); | ||
OffsetDateTime tokenExpiryThreshold = OffsetDateTime.now().plusMinutes(5); | ||
if (accessToken.getExpiresAt() != null && accessToken.getExpiresAt().isBefore(tokenExpiryThreshold)) { | ||
log.info("Access token is about to expire (5 minutes or less) at: {}. New access token will be generated", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
log.info("Access token is about to expire (5 minutes or less) at: {}. New access token will be generated", | |
log.info("Access token is about to expire (20 minutes or less) at: {}. New access token will be generated", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above.
Azure Access token is valid for 1 hour only. Added code to check for token expiry every 4 minutes, and refresh the token when the same is close to expiry.