11

I've got access_token from Azure Ad V2.0 endpoint to call Graph Api. But I have to do some actions in the api on behalf of user. So I need refresh_token to renew my access_token when it'll expire.

Is there any way to get Refresh token using MSAL in ASP .Net Core?

In microsoft documentaion they're telling it's possible to do by requesting /token endpoint. But I couldn't find how to do it using MSAL.

S. Anna
  • 121
  • 1
  • 3
  • 2
    MSAL usually handles the refresh token for you. You would need to implement the token cache properly for your app. – juunas Feb 23 '18 at 17:09
  • Is there any way to get it? I'll keep it in a database or Azure KeyVault – S. Anna Feb 24 '18 at 18:27
  • I *think* there is no API to get them. The way to implement what you want would be to make a token cache class which handles storing the data (and loading it) in Key Vault for example. – juunas Feb 24 '18 at 18:29
  • Though you should also add some in-memory caching in that case.. You don't want to hit Key Vault every single time. – juunas Feb 24 '18 at 18:30
  • You can look through the MSAL source if you want :) https://github.com/AzureAD/microsoft-authentication-library-for-dotnet – juunas Feb 24 '18 at 18:30

3 Answers3

7

MSAL .NET does not expose the refresh token, but rather keeps it internal and handles all token refresh and caching logic on the app's behalf.

The docs you're referring to are referencing the protocol itself that MSAL is completing on your behalf. It goes to the /token endpoint with an authorization code (after the end user signs in), and is issued an Access and Refresh token. The Access Token is valid for 1 hour, and when it's expired, AcquireTokenSilent will automatically use the refresh token against the /token endpoint to get a new access token.

Daniel Dobalian
  • 3,129
  • 2
  • 15
  • 28
  • 1
    Thanks for the answer. I am using microservices architecture, so my back and front services are apart. The problem is to get access token from front service (js) and send it to .net core web api (back). Back service will call graph api and do some other things using this token. So I need to have refresh token in my back-end service to be able to manage tokens. – S. Anna Feb 26 '18 at 08:40
  • @S.Anna Have you taken a look at the [on-behalf-of flow](https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-protocols-oauth-on-behalf-of)? I think it would be perfect for this scenario. Basically, your client app will get a token and send it to your backend (just like before). Then, the backend can send this token to Azure AD for a new token that can be used for a downstream API like the Microsoft graph. – Daniel Dobalian Feb 28 '18 at 01:06
  • I've looked through the documentation. Now I want to implement on-behalf-of-flow scenario using MSAL and can't find any documentation. Can you help with any kind of example how to do it? – S. Anna Mar 01 '18 at 16:48
  • We don't have a code sample on the on-behalf-of flow yet, but [here's](https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-protocols-oauth-on-behalf-of) the reference docs on the protocol which should get you on the right path. – Daniel Dobalian Mar 02 '18 at 06:11
  • whilst this answer is correct when accessing pages, if youre on the same page and make an ajax request, this is not the case. – traveler3468 Jun 15 '20 at 12:44
  • My IDTokens are 1hr expiry, RefreshTokens 8hr... when the 8hrs is up, MSAL gives up just throws an exception when trying to get a new IDToken. Shouldn't it also manage the RefreshTokens by getting a new one when required? – pseabury Sep 18 '20 at 13:36
2

I got a bit topsy-turvy on this, as well. Explaining a bit more based on my understanding.

  • For context, OAuth 2.0 code grant flow mentions the following steps:
    • authorization, which returns auth_code
    • using auth_code, to fetch access_token (usually valid for 1 hr) and refresh_token
    • access_token is used to gain access to relevant resources
    • after access_token expires, refresh_token is used to get new access_token
  • MSAL.NET abstracts this concept of refresh_token via TokenCache.
    • There is an option to serialize TokenCache. See Token cache serialization in MSAL.NET. This is how to preserve sign-in info b/w desktop application sessions, and avoid those sign-in windows.
    • AcquireTokenSilentAsync is the process by which refresh_token is used to get new access_token, but, this is internally done. See AcquireTokenSilentAsync using a cached token for more details and other access patterns.

Hope this clarifies on why TokenCache is the 'new' refresh_token in MSAL.NET, and TokenCache is what you would need to serialize and save. There are libraries like Microsoft.Identity.Client.Extensions.Msal that aid in this.

AAATechGuy
  • 385
  • 2
  • 9
1

TokenCache is basically a JSON object which is served as byte array when you call SerializeMsalV3(). When you convert byte array to string, you will see both access token and refresh token. Then you can make a HTTP request to \token endpoint with this refresh token and grant_type: "refresh_token" body parameters.

IConfidentialClientApplication capp =
                    ConfidentialClientApplicationBuilder.Create(myClientId)
                        .WithClientSecret(myclientSecret)
                        .Build();

    capp.UserTokenCache.SetAfterAccess((TokenCacheNotificationArgs args) =>
    {
       exchangeTokenCacheV3Bytes = args.TokenCache.SerializeMsalV3();
       string jsonString = System.Text.Encoding.UTF8.GetString(exchangeTokenCacheV3Bytes);
    });