I'm moderately familiar with OAuth2 and the concepts of the AccessToken and RefreshToken.
It looks like MSAL is doing some work for us when using ClientApplicationBase.AcquireTokenSilentAsync().
I'm not clear as to whether it will always check the expiration of the current AccessToken and automatically refresh it (using the RefreshToken) on method call.
Regardless, is there a "best practice" for how often we should call AcquireTokenSilentAsync() ? Should we keep track of the expiration ourselves and call this method to update our bearer authentication header? Should we be calling AcquireTokenSilentAsync() on every Request? (doubtful)
I can't see how the GraphServiceClient (tangent topic, I know) using the DelegateAuthenticationProvider will do anything helpful WRT refreshing. Do we need to extend that class and perform our own refresh when the token is nearing expiration? I feel like this would/should be already in the SDK.
Thanks for any tips. -AJ
These client credentials and the refresh_token can be used to create a new value for the access_token . To refresh the access token, select the Refresh access token API call within the Authorization folder of the Postman collection. Next, click the Send button to request a new access_token .
In MSAL, you can get access tokens for the APIs your app needs to call using the acquireTokenSilent method which makes a silent request(without prompting the user with UI) to Azure AD to obtain an access token.
Use the refresh token to get a new access token Access tokens are short lived, and you must refresh them after they expire to continue accessing resources. You can do so by submitting another POST request to the /token endpoint, this time providing the refresh_token instead of the code .
Go to Services > Azure Partner (NCE) > Manage Refresh Token. In the Manual Update group, specify the authentication code that you received and click Update. Make sure that a message similar to Your refresh token has been successfully updated is shown.
Update Nov 2020
This answer was originally written for V2 of the MSAL client. Since then a V3 has been released which may work differently from V2.
Original answer
I'm not clear as to whether it will always check the expiration of the current AccessToken and automatically refresh it (using the RefreshToken) on method call.
A refresh token is automatically supplied when the offline_access
scope is provided, if I understand this answer correctly
...you've requested the
offline_access
scope so your app receives a Refresh Token.
The description of AcquireTokenSilentAsync
implies that when an refresh token is provided, it will check the expiration date on the token, and get a new one if it's expired or close to expiring.
If access token is expired or close to expiration (within 5 minute window), then refresh token (if available) is used to acquire a new access token by making a network call.
It will repeat this behavior until the refresh token is expired. Optionally you can force a refresh of the access token via the refresh token by utilizing the forceRefresh
parameter on AcquireTokenSilentAsync
Lastly, I am going to quote this answer on SO since it gives a nice insight about MSAL and tokens
Just to make a small clarification, MSAL doesn't actually issue tokens or decide a token expiration, but rather ingests an acquires token from the Azure AD STS.
MSAL will automatically refresh your access token after expiration when calling AcquireTokenSilentAsync. .... The default token expirations right now are:
Access Tokens: 1 hour
Refresh Tokens: 90 days, 14 day inactive sliding window
(June 13th '17)
Regardless, is there a "best practice" for how often we should call AcquireTokenSilentAsync() ? Should we keep track of the expiration ourselves and call this method to update our bearer authentication header? Should we be calling AcquireTokenSilentAsync() on every Request?
The documentation also lists a 'Recommended call pattern' for calling the AcquireTokenSilentAsync
. The documentation also mentions that
For both Public client and confidential client applications, MSAL.NET maintains a token cache (or two caches in the case of confidential client applications), and applications should try to get a token from the cache first before any other means.
Based on examples I've seen, including the recommended call pattern from the documentation, I would argue you could simply call AcquireTokenSilentAsync
and catch the MsalUiRequiredException
as an indication that the token has expired and the user has to log in again.
I can't see how the GraphServiceClient (tangent topic, I know) using the DelegateAuthenticationProvider will do anything helpful WRT refreshing. Do we need to extend that class and perform our own refresh when the token is nearing expiration? I feel like this would/should be already in the SDK.
If I understand the DelegateAuthenticationProvider correctly, what it does is modify the requestMessage before we pass it to Graph. All we got to do is provide our access token with an authorization header for the request. We already know that when we fetch our access token, it is valid, so we can just add it.
new DelegateAuthenticationProvider(async (requestMessage) =>
{
ConfidentialClientApplication cca = new ConfidentialClientApplication(_ClientId, _Authority, _RedirectUri, new ClientCredential(_ClientSecret), _UserTokenSessionCache.GetTokenCache(identifier, httpContext), _ApplicationTokenCache.GetTokenCache());
AuthenticationResult result = await cca.AcquireTokenSilentAsync();
requestMessage.Headers.Add("Authorization", result.CreateAuthorizationHeader());
//OR
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", result.AccessToken);
});
(There is no difference between either way of setting the headers)
I've been down this path and this does the trick for me. I highly advise reading their documentation, because it does gives a good insight in how to implement MSAL.Net.
I haven't had time yet to play around with the token durations yet. Nor the behavior if no refresh token is provided (if that's even possible)
I hope this helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With