0

I was looking here about refresh tokens.

I have this code to get a access token:

if(bPromptUser)
{
    _AuthResult = await PublicClientApp.AcquireTokenAsync(_scopes); //Opens Microsoft Login Screen

    using (RegistryKey key = Registry.CurrentUser.CreateSubKey(keyName))
    {
        key.OpenSubKey(keyName, true);
        key.SetValue("Status", _AuthResult.AccessToken);
        key.SetValue("Expire", _AuthResult.ExpiresOn.ToLocalTime().ToString());
        key.Close();

        token = _AuthResult.AccessToken;
    }

    // Append the access token to the request.
    requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", token);
}

But my _AuthResult doesn't actually have a RefreskToken in the list. Is this because I am using v1 of Microsoft Graph?

Update

According to the documentation the scope suggested in the answer is on by default?

enter image description here

Andrew Truckle
  • 17,769
  • 16
  • 66
  • 164

3 Answers3

0

I believe when using MSAL (and the v2 auth endpoint) that you don't get a refresh token by default. To get the refresh token you need to request the offline_access scope as well as the other scopes. Please see https://developer.microsoft.com/en-us/graph/docs/concepts/permissions_reference#openid-permissions for more details.

Hope this helps,

Dan Kershaw - MSFT
  • 5,833
  • 1
  • 14
  • 23
  • Thanks. I just looked at the topic. Please see my updates question. – Andrew Truckle Sep 07 '17 at 04:34
  • 1
    Will ask someone else to take a look at this. – Dan Kershaw - MSFT Sep 07 '17 at 05:27
  • Have a look here: https://stackoverflow.com/questions/34202782/how-to-get-a-refresh-token-and-access-token-in-office-365-using-php The answer provides a link. The wording does not mention defaults there. So articles saying mixed things. – Andrew Truckle Sep 07 '17 at 18:47
  • This was it: https://developer.microsoft.com/en-us/graph/docs/concepts/auth_v2_user – Andrew Truckle Sep 07 '17 at 18:57
  • If you look at the extracted code for AuthResult it doesn't even have a property for a refresh token. – Andrew Truckle Sep 08 '17 at 06:59
  • @AndrewTruckle as your update suggests, MSAL automatically passes `offline_access` in all requests and manages all token refreshes for you. The refresh token is stored in the cache and used internally in MSAL to refresh any expired tokens. As an abstraction, It is not accessible via the library. Checkout [all the available fields in the source](https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/blob/dc3f0656b7f8b8d6f474a8ed19c671dd51626459/src/Microsoft.Identity.Client/AuthenticationResult.cs), and can open an issue on the library if you believe it should be exposed! – Daniel Dobalian Sep 09 '17 at 00:00
  • @DanielDobalian All I know is that after the access token has expired I will always be prompted for credentials. So what you say doesn't make sense to me in my situation. – Andrew Truckle Sep 09 '17 at 12:17
  • There could be an issue with your token cache or how you're making library calls. Can you update your question (or post a new one) with the MSAL and token cache code? – Daniel Dobalian Sep 12 '17 at 23:14
0

Microsoft provide sample code for TokenCacheHelper.

Add that to your project and provide an instance of it. Then, set the path. Like this:

TokenCacheHelper.CacheFilePath = Program.Options.TokenCachePath;
PublicClientApp = new PublicClientApplication(_AppID, "https://login.microsoftonline.com/common", TokenCacheHelper.GetUserCache());

That is all you need to do. The cache file contains all the token details, including the refresh token.

More details are in the conversation here. In part:

As far as helping you to implement the token cache, to store the content of the token cache, you need to:

  1. Copy the TokenCacheHelper from here to your project.
  2. If you really want to save the content of the cache to the registry, change the implementation of:
    • AfterAccessNotification to write to the registry instead of a file this line
    • BeforeAccessNotification to read fromthe registry instead of a file this line
  3. Construct the PublicClientApplication your as shown here (passing the cache that you get by calling TokenCacheHelper.GetUserCache(): https://github.com/Azure-Samples/active-directory-dotnet-desktop-msgraph-v2/blob/master/active-directory-wpf-msgraph-v2/App.xaml.cs#L19:

    clientApp = new PublicClientApplication(ClientId, "https://login.microsoftonline.com/common", TokenCacheHelper.GetUserCache());

Andrew Truckle
  • 17,769
  • 16
  • 66
  • 164
0

For me, my problem was using an older version of the Microsoft.Identity.Client nuget package. Upgrading from 4.35.1 to 4.40.0 fixed the token error.