Forum Discussion
'Generate Token' API returns token with variable (short) expirations: Using Service Principal
- Anonymous6 years ago
Hi basvanleeuwen
I ended up taking a different route in the end, adding details here for others...
The C# flow for creating an Authentication Context and passing in details for the Service Principal, results in the Azure auth token being cached within your application/api. After the first request, this cached token is then used for approximately 55 minutes (as you had noticed) - but you can manipulate this cache in code.
C# even lets you handle the serialization of these tokens in cases where you don't want to use the built-in cache.
https://github.com/AzureAD/azure-activedirectory-library-for-dotnet/wiki/Token-cache-serialization
I didn't go the full custom serialization route, instead I opted for a simple cache invalidation method.private async Task<AuthenticationResult> CallAuthTokenEndpoint() { var authenticationContext = new AuthenticationContext("https://login.microsoftonline.com/..."); var credential = new ClientCredential("abcd-1234-your-auth-client-id", "your-client-secret"); ClearExpiredTokenCache(authenticationContext); return await authenticationContext.AcquireTokenAsync("https://analysis.windows.net/powerbi/api", credential); } private void ClearExpiredTokenCache(AuthenticationContext authenticationContext) { var cachedItems = authenticationContext.TokenCache.ReadItems(); var matchedItem = cachedItems.FirstOrDefault(tokenCacheItem => string.Compare(tokenCacheItem.ClientId, "abcd-1234-your-auth-client-id", StringComparison.OrdinalIgnoreCase) == 0 && string.Compare(tokenCacheItem.Resource, "https://analysis.windows.net/powerbi/api", StringComparison.OrdinalIgnoreCase) == 0); if (matchedItem != null) { var expireIfAfter = DateTime.UtcNow.AddMinutes(50); if (expireIfAfter > matchedItem.ExpiresOn) { authenticationContext.TokenCache.DeleteItem(matchedItem); } } }CallAuthTokenEndpoint => Is responsible for getting the Azure Auth Token, which will then be used by the Power BI API.
The call to AquireTokenAsync in this method, will return from the local cache (if a token has been generated within the last 55 minutes). So before calling this method, we can do our own clearing of the token cache - via the Authentication Context.
ClearExpiredTokenCache => fetches all items from the local cache. Then finds the one that matches our ClientId and desired resource (analysis.windows.net/powerbi/api).
If we find a matching token... then we can choose to clear it from the cache IF more than 10 minutes have passed. (Utc.Now + 50 mins).
With no token in the cache, the call to AquireTokenAsync will always generate a new token with another 60 minutes on the clock.
This obviously results in increased frequency of calls to Azure for auth tokens... but it gives you more flexibility for manging token durations.
I am assuming that the Power BI token expiration being in-sync with the expiration of the Azure AD token, is by design.
Hopefully one of our suggestions will help other people in similar situations,
Cheers, Matt
Yes, indeed Anonymous, we are facing the exact same behaviour. The expiration of the token remains the same upon each new token-request, which doesn't seem to be normal.
However, It looks like (approx.) 5 minutes before the expiration a new token can be requested which will give a new expiration time. We were able to handle this with a timer (within our SPA) that ends 5 minutes before the tokens' expiration, after which it will fetch a new token with a fresh expirationtime.
- Anonymous6 years agoNot applicable
Hi basvanleeuwen
I ended up taking a different route in the end, adding details here for others...
The C# flow for creating an Authentication Context and passing in details for the Service Principal, results in the Azure auth token being cached within your application/api. After the first request, this cached token is then used for approximately 55 minutes (as you had noticed) - but you can manipulate this cache in code.
C# even lets you handle the serialization of these tokens in cases where you don't want to use the built-in cache.
https://github.com/AzureAD/azure-activedirectory-library-for-dotnet/wiki/Token-cache-serialization
I didn't go the full custom serialization route, instead I opted for a simple cache invalidation method.private async Task<AuthenticationResult> CallAuthTokenEndpoint() { var authenticationContext = new AuthenticationContext("https://login.microsoftonline.com/..."); var credential = new ClientCredential("abcd-1234-your-auth-client-id", "your-client-secret"); ClearExpiredTokenCache(authenticationContext); return await authenticationContext.AcquireTokenAsync("https://analysis.windows.net/powerbi/api", credential); } private void ClearExpiredTokenCache(AuthenticationContext authenticationContext) { var cachedItems = authenticationContext.TokenCache.ReadItems(); var matchedItem = cachedItems.FirstOrDefault(tokenCacheItem => string.Compare(tokenCacheItem.ClientId, "abcd-1234-your-auth-client-id", StringComparison.OrdinalIgnoreCase) == 0 && string.Compare(tokenCacheItem.Resource, "https://analysis.windows.net/powerbi/api", StringComparison.OrdinalIgnoreCase) == 0); if (matchedItem != null) { var expireIfAfter = DateTime.UtcNow.AddMinutes(50); if (expireIfAfter > matchedItem.ExpiresOn) { authenticationContext.TokenCache.DeleteItem(matchedItem); } } }CallAuthTokenEndpoint => Is responsible for getting the Azure Auth Token, which will then be used by the Power BI API.
The call to AquireTokenAsync in this method, will return from the local cache (if a token has been generated within the last 55 minutes). So before calling this method, we can do our own clearing of the token cache - via the Authentication Context.
ClearExpiredTokenCache => fetches all items from the local cache. Then finds the one that matches our ClientId and desired resource (analysis.windows.net/powerbi/api).
If we find a matching token... then we can choose to clear it from the cache IF more than 10 minutes have passed. (Utc.Now + 50 mins).
With no token in the cache, the call to AquireTokenAsync will always generate a new token with another 60 minutes on the clock.
This obviously results in increased frequency of calls to Azure for auth tokens... but it gives you more flexibility for manging token durations.
I am assuming that the Power BI token expiration being in-sync with the expiration of the Azure AD token, is by design.
Hopefully one of our suggestions will help other people in similar situations,
Cheers, Matt