App Service Token Store

The App Service Token Store is an advanced capability that was added to the Authentication / Authorization feature (a.k.a. “Easy Auth”) of App Service. Like the name implies, the token store is a repository of OAuth tokens that are associated with the end-users of your app.

When a user logs into your app via an identity provider, such as Azure Active Directory or Facebook (or any of the other supported providers), the identity provider provides one or more tokens that 1) prove the user’s identity and may also 2) provide access to resources owned by that user. By default, all new App Service apps with auth configured will have a built-in token store which your app code can immediately take advantage of. Support is included for Web Apps, Mobile Apps, and API Apps and is available in all SKUs.

Common Scenarios for the Token Store

Lets say you’re building an app and you want the ability for users to log in with their Facebook account credentials. Lets also say that you want your app post to their Facebook timelines on their behalf. In order to call the Facebook API to perform such an action, you would need an OAuth token issued by Facebook with the proper permissions to do this. The token store is for automatically collecting and storing these tokens and making it easy for your app to access them.

Similarly if you are writing an app which needs to call into the Azure Active Directory Graph API or even the Microsoft Graph on behalf of a user in your corporate directory, your app can be configured to store the required access token in the token store automatically. More details on how to configure your AAD applications for Graph API access will come in a subsequent post.

While convenient, not all apps require these capabilities. If, for example, you’re only using built-in authentication to protect access to a staging slot and don’t need to actually do anything with these extra tokens, then you likely don’t need to use the token store and can safely disable the feature.

Accessing the Tokens

From within your backend code, accessing these tokens is as easy as reading an HTTP request header. The headers are named like X-MS-TOKEN-{provider}-{type}. The possible token header names are listed below:

Azure Active Directory Token Request Headers

  • X-MS-TOKEN-AAD-ID-TOKEN
  • X-MS-TOKEN-AAD-ACCESS-TOKEN
  • X-MS-TOKEN-AAD-EXPIRES-ON
  • X-MS-TOKEN-AAD-REFRESH-TOKEN

Facebook Token Request Headers

  • X-MS-TOKEN-FACEBOOK-ACCESS-TOKEN
  • X-MS-TOKEN-FACEBOOK-EXPIRES-ON

Google Token Request Headers

  • X-MS-TOKEN-GOOGLE-ID-TOKEN
  • X-MS-TOKEN-GOOGLE-ACCESS-TOKEN
  • X-MS-TOKEN-GOOGLE-EXPIRES-ON
  • X-MS-TOKEN-GOOGLE-REFRESH-TOKEN

Microsoft Account Token Request Headers

  • X-MS-TOKEN-MICROSOFTACCOUNT-ACCESS-TOKEN
  • X-MS-TOKEN-MICROSOFTACCOUNT-EXPIRES-ON
  • X-MS-TOKEN-MICROSOFTACCOUNT-AUTHENTICATION-TOKEN
  • X-MS-TOKEN-MICROSOFTACCOUNT-REFRESH-TOKEN

Twitter Token Request Headers

  • X-MS-TOKEN-TWITTER-ACCESS-TOKEN
  • X-MS-TOKEN-TWITTER-ACCESS-TOKEN-SECRET

Querying the request headers is the simplest method for obtaining these user-specific OAuth tokens. No SDKs, external API calls, database queries, or file access is required (this is a general theme you’ll see repeated when it comes to Easy Auth). The values of these headers are the raw token values and can be used as-is when calling into the provider APIs. No parsing necessary.

To see which tokens are available to your app for a particular user, try logging in and enumerating the request headers. These headers are added by the local IIS module, which I discussed in a previous post on the App Service Auth Architecture.

If you want to access the tokens from a client (like JavaScript in a browser), or if you want to get a richer set of information about the logged in user, you can also send an authenticated GET request to the local /.auth/me endpoint. Whatever authentication method you use to access your app (cookies or tokens) can be used to access this API. The request format is very simple:

GET /.auth/me

…which returns a JSON response that looks like the following:

[{
  "provider_name":"<provider>",
  "user_id": "<user_id>",
  "user_claims":[{"typ": "<claim-type>","val": "<claim-value>"}, ...],
  "access_token":"<access_token>",
  "access_token_secret":"<access_token_secret>",
  "authentication_token":"<authentication_token>",
  "expires_on":"<iso8601_datetime>",
  "id_token":"<id_token>",
  "refresh_token":"<refresh_token>"
}]

This API is what the App Service Server SDK uses internally to fetch information about the currently logged-in user.

No matter which method you choose, the actual tokens available depend on what provider was used to log into the app as well as which scopes were configured for that provider. For example, a Google login will always include an access token, but will only include a refresh token if the offline access scope is configured.

Where the Tokens Live

Internally, all these tokens are stored in your app’s local file storage under D:/home/data/.auth/tokens. The tokens themselves are all encrypted in user-specific .json files using app-specific encryption keys and cryptographically signed as per best practice. This is an internal detail that your app code does not need to worry about. Just know that they are secure. While you could write code to read and decrypt these token store files, we recommend against doing so as the format could be changed in a future service update.

The app’s distributed file storage was chosen as the default location for storing tokens because it’s freely available to all App Service apps without any additional configuration. However, the file system token store may not be ideal for all customers. In particular, it does not scale well when large numbers of concurrent logins are expected and is incompatible with the local disk caching feature of App Service.

As an alternative, you can provision an Azure Blob Storage container and configure your web app with a SaS URL (with read/write/list access) pointing to that blob container. This SaS URL can then be saved to the WEBSITE_AUTH_TOKEN_CONTAINER_SASURL app setting. When this app setting is present, all tokens will be stored in and fetched from the specified blob container.

As a warning, this blob storage capability should be considered experimental until further notice. Also note that any existing tokens are not migrated to the new store. If you make this configuration change, users will need to re-authenticate with the app in order for their tokens to become available.

Refreshing Tokens

An important detail about using access tokens is that most of them will eventually expire. Some providers, like Facebook, have access tokens which expire after 60 days. Other providers, like Azure AD, Microsoft Account, and Google, issue access tokens which expire in 1 hour. In all cases, a fresh set of tokens can be obtained by forcing the user to re-authenticate. This is reasonable for Facebook since a re-auth would only need to happen once every 60 days. However, this is not practical for Azure AD, Microsoft Account, and Google, where the token expiration is 1 hour.

To avoid the need to re-authenticate the user to get a new access token, you can instead issue an authenticated GET request to the /.auth/refresh endpoint of your application. This is a built-in endpoint, just like /.auth/me. When called, the Easy Auth module will automatically refresh the access tokens in the token store for the authenticated user. Subsequent requests for tokens by your app code will then get the most up-to-date tokens. In order for this to work, the token store must contain refresh tokens for your provider. If you’re not familiar with how to do this, here are some hints:

  • Google: Append an “access_type=offline” query string parameter to your /.auth/login API call (if using the Mobile Apps SDK, you can add this to one of the LogicAsync overloads).
  • Microsoft Account: Select the wl.offline_access scope in the Azure management portal.
  • Azure AD: This is a little complex right now, but take a look at my next post on enabling Graph API access. Follow the setup steps and this will also enable you to get refresh tokens for Azure AD (you can omit the Read directory data and the resource=… parts if they don’t apply to you). The plan is to simplify this in the future.

Here is an example snippet which refreshes tokens from a JavaScript client (with jQuery). Similar logic could have been written in other languages as well:

function refreshTokens() {
  var refreshUrl = "/.auth/refresh";
  $.ajax(refreshUrl) .done(function() {
    console.log("Token refresh completed successfully.");
  }) .fail(function() {
    console.log("Token refresh failed. See application logs for details.");
  });
}

It’s important to note that the /.auth/refresh API is not guaranteed to succeed. For example, a user is free to revoke the permissions granted to your app at any time. In such cases, any attempt to refresh existing access tokens will fail with a 403 Forbidden response. Also, if your auth provider is not configured to return refresh tokens (e.g. you did not request the appropriate offline scope), you can expect this to fail with a 400 Bad Request response. In either case, you can check your application logs for details (assuming you have already enabled application logging).

If you are a mobile app and use App Service Mobile SDK, which internally uses the x-zumo-auth header to authenticate with your App Service backend, you may be aware of the fact that your x-zumo-auth JWT may also have a short expiration. This mobile authentication token can also be refreshed using the /.auth/refresh endpoint. Just send a GET request to /.auth/refresh with the x-zumo-auth header (present by default when using the mobile client SDK), and the endpoint will respond with a new authentication token for use by your application. Note that the same restrictions regarding refresh tokens still apply.

If you’re building your client using one of the Azure Mobile Client SDK flavors, then you can use the RefreshUser method to refresh both the local authentication token as well as the provider tokens. More documentation on RefreshUser can be found at https://azure.microsoft.com/en-us/blog/mobile-apps-easy-authentication-refresh-token-support/.

Here is an example snippet in C#:

async Task<string> GetDataAsync()
{
  try
  {
    return await App.MobileService.InvokeApiAsync<string>("values");
  }
  catch (MobileServiceInvalidOperationException e)
  {
    if (e.Response.StatusCode != HttpStatusCode.Unauthorized)
    {
      throw;
    }
  } 

  // Internally calls /.auth/refresh to update the tokens in the token store
  // and will also update the authentication token used by the client.
  await App.MobileService.RefreshUser();

  // Make the call again, this time with a fresh authentication token.
  return await App.MobileService.InvokeApiAsync<string>("values");
}

As shown in the above, the code handles the unauthorized response, refreshes the authentication token, and makes the call again. Note that this code sample is meant to be simple and trivial. Your implementation will certainly be more robust.

You may have also noticed that this example calls into the /.auth/refresh API with an expired authentication token. This is allowed in the first 72-hours after expiration and simplifies token management by not requiring you to track expirations yourself. If the authentication token is not refreshed within the 72-hour window, a fresh re-auth by the end-user will be required to get a new, non-expired authentication token.

Advanced: Several folks have asked about this, so we’ve made an update such that if 72 hours is not enough for you, you can customize this expiration window by adding a tokenRefreshExtensionHours value in the site/config/authSettings configuration in Azure Resource Explorer. Be warned that extending the expiration over a long period could have significant security implications – e.g. if an authentication token is leaked or stolen, so it’s highly recommended to either leave it at the default 72 or set it to the smallest value necessary. The default of 72 hours was chosen to account for cases where a mobile app is used primarily on weekdays and goes inactive over the weekend.

Wrapping Up

As always, let me know in the comments if you have any feedback on the content of this post. If you have general questions or if you’re running into issues, I suggest posting on StackOverflow (please tag your questions with azure-app-service or azure-web-sites) or the forums so that others can easily find, rate, and participate in the discussion. For the highest level of support, take a look at some of our support plans. This is absolutely the best way to get our attention and prioritize any issues you may encounter.

If you have feature requests, I suggest you post and/or vote on one of our UserVoice pages (web apps, mobile apps, API apps). I’m always trying to think about how we can improve the feature in ways that make the most sense to real-life developers.

Also, feel free to reach out to me directly on Twitter.

Author: cgillum

Principal Software Engineer at Microsoft.

69 thoughts on “App Service Token Store”

  1. I’m curious on where there is a 72-hour limit on getting the token refreshed:

    “This is allowed in the first 72-hours after expiration and simplifies token management by not requiring you to track expirations yourself. If the authentication token is not refreshed within the 72-hour window, a fresh re-auth by the end-user will be required to get a new, non-expired authentication token.”

    I can see many cases where the user uses the app on a week by week basis rather than daily. Having to re-auth every week can become cumbersome. Are there plans to let us choose the timeframe for renewal?

    Thanks,

    John

    1. John, thanks for the feedback. The 72-hour limit was chosen to cover the case where a mobile app is active during the week but inactive over the weekend. The reason to make the time more limited is to reduce the chance that a lost/stolen token can be used by an attacker to obtain access to the app. We could expand the lifetime to 7 days, but that increases risk. As an alternative, could a mobile app use background processing to periodically refresh the token in the background?

    2. Ditto here, too.

      In fact, the app I’m trying to write will probably have a usage pattern such that they’ll have to login each time they launch the app. That won’t be popular.

      It’s a Xamarin Forms app which means background operations will probably be platform specific and largely not appreciated.

      Something definable in portal would be nice if it were possible.

    3. Just re-read what I typed.

      I meant background apps not appreciated by the **user** (traffic, battery life, etc.).

      I’m happy with almost anything. 🙂

    4. Thanks for the feedback, Bill. It sounds like it would be helpful to make this configurable as you and John suggested. I’ll put this on our backlog since it sounds like it would be helpful for a variety of mobile apps.

    5. +1. I agree that making 72hrs configurable in portal will be suitable for a various app usage consideration.
      We have various customers’ apps demands. 🙂

      Much appreciated.

    6. Thanks for the feedback. We’ve recently added support for this, though it’s not currently exposed by the portal. If you’re comfortable using Resource Explorer to manage your site’s auth settings, you can add a setting named “tokenRefreshExtensionHours” to {site}/config/authSettings.properties and set it to the number of hours to allow an expired token to be used for refresh. At some point I’ll try to update the post with more detailed instructions.

  2. Great to see refresh token support.
    Would be great to get some documentation on how refresh tokens can be issued / saved using custom authentication

  3. What a great explanation. Thanks for very much. I couldn’t find a thing about the Token Store anywhere else except this blog. Huge help.

  4. Hi

    Great explanation! Regarding the use of refresh tokens you state the following : “For example, a Google login will always include an access token, but will only include a refresh token if the offline access scope is configured.”

    I’ve managed to set and get the refresh token for Microsoft Account by specifying the offline scope in my Azure Mobile App but I cannot figure out how to do this for Google Accounts. Nothing in the linked guide on the Azure Portal (https://azure.microsoft.com/en-us/documentation/articles/app-service-mobile-how-to-configure-google-authentication/) or elsewhere. Where do you set the scope for Google Accounts?

    Have a nice day!

    1. Hasse, thanks for bringing this up! It turns out that getting offline access for Google is a little different from what I described (I need to update my post). The proper way to get the refresh token for Google is to specify a access_type=offline query string parameter in your LoginAsync call. Things vary across the different versions of Mobile Client SDKs, but you should be able to find an overload which allows you to specify additional login parameters.

    2. Google scopes can be specified by adding a “scope” query string parameter to your login API call.

  5. Hi cgillum,
    Thanks for this great explanation.
    I am having the following issue: when calling the “/.auth/refresh” url from my MobileServiceClient as described in your C# example I am getting a “StatusCode: 400, ReasonPhrase: ‘Bad Request'” response.

    Do you have any idea what causes this issue?

    Thanks,
    Andreas

    1. Hi Andreas. You can find the specific reason for the failure by turning on application logging in the management portal and then reproducing the issue. The resulting log output will show you what the problem was. Most likely it means you don’t have a refresh token in the token store. You can confirm this by calling the /.auth/me endpoint and seeing whether the response includes a refresh_token field.

  6. Hi cgillum,

    Thank you very much for your quick reply.
    My problem was that I didn´t have the offline scope activated in the portal.
    Problem solved 🙂

  7. Useful information, thank you.

    I’m wondering if its a good / bad idea to pro-actively refresh?

    I’m using all sorts of features of the App Service Mobile SDK and its friends, which often trigger api calls in a non-deterministic fashion. For example, calling purgeasync, or pullasync on an IMobileServiceSyncTable automatically triggers a push of data that hasn’t been synced.

    So I am sort of wondering if I could keep a track of when the last /.auth/refresh was called, and when approaching or exceeding an hour I might refresh before making any server requests.

  8. Hello. Thanks for the post. Where you say “(which can be made available to your app by requesting offline access scopes in your auth configuration).” , it is not clear to me how that can be done for a an Azure AD provider? I have dug around but I can’t guess how this is done?

    Cheers.

    1. Ross, take a look at my next post on working with the Azure AD Graph API: https://cgillum.tech/2016/03/25/app-service-auth-aad-graph-api/. The setup instructions describe how to enable Graph API access, but if you follow these instructions, it will also allow you to get a refresh token for AAD. If you don’t want Graph API access, you can simplify those instructions by removing “Read directory data” from step #1 and removing “resource=https://graph.windows.net” from step #2.

    2. Hi – Great article but struggling to get over the line.

      I’m using a Mobile App (Universal) with AzureAD. I can loginaysnc fine and I’ve also enabled graph access as per your March 31, 2016 at 3:54 pm reply.

      However, when I run await MobileService.InvokeApiAsync(“/.auth/refresh”,HttpMethod.Get,null);

      I get {StatusCode: 403, ReasonPhrase: ‘Forbidden’, Version: 1.1

      I’m also running the auth code in the Windows runtime component.

      Any ideas?

    3. failedRequest url=”https://TrackerTo:80/.auth/refresh”
      siteId=”664475180″
      appPoolId=”TrackerTo”
      processId=”9196″
      verb=”GET”
      authenticationType=”NOT_AVAILABLE” activityId=”{00000000-0000-0000-FE08-0080000000E9}”
      failureReason=”STATUS_CODE”
      statusCode=”403.80″
      triggerStatusCode=”403.80″
      timeTaken=”62″
      xmlns:freb=”http://schemas.microsoft.com/win/2006/06/iis/freb”

  9. Great description on the Token Store. You talk about refreshing tokens and how one would go about doing this but what about clearing/removing the tokens that have been persisted on a users device – use case here would be a mobile app (Xamarin) that allows multiple Identity Provider authentication. You may want to logon (say) as user1 for your facebook account and then you might want to logout and then logon as user2 on facebook. Assuming authentication has been setup on Azure portal via Mobile App->Settings->Authentication/Authorization and all IP’s have been configured accordingly. Additionally, you will use (say) the following code to authenticate your client :

    LoginAsync(…)

    The very first time the LoginAsync is called and assuming there is no valid token (that exists on the device) for the MobileServiceAuthenticationProvider that is supplied as a parameter to LoginAsync – then the MobileServiceAuthenticationProvider’s logon window will be shown.

    Now if we then issue a LogoutAsync and then go back to clicking on a button to Logon again (to the same MobileServiceAuthenticationProvider) one would hope that the Logon page would be shown – this doesnt happen as the token still exists on the device. So – if we wanted to allow multiple users for a provider to logon-logoff accordingly, what is the recommended way for this to be accomplished ?

  10. I’m a bit new to this. Am I understanding this correctly that a Windows 10 UWP app using a Microsoft Account to authenticate with an Azure Mobile App will require a token refresh before 72 hours of initial authentication?

    Is it advisable refresh token in a background task to hopefully allow users from ever seeing a login prompt?

    1. Yes, refreshing in a background task is a great way to ensure your users never see a login prompt. Microsoft Account tokens only last an hour, so theoretically you’ll have 73 hours to do the refresh.

  11. I am using Twitter for signing in, and Azure Web API is issuing a token that lasts a month, which is great. However when I send a request to .auth/refresh I get Bad REquest. Is this by design? Can I refresh my Azure Api token, issued with twitter sign in?

    1. Unfortunately Twitter doesn’t support token refresh. This is why you are seeing Bad Request. However, the token you receive after a twitter login should be lasting you 30 days. When it expires, you’ll need to initiate a new login.

  12. Hi Chris,
    I have a question regarding the following scenario:
    I have an Azure Api App managing all the authentication stuff with microsoft account, twitter etc. described above.
    Then I have a Windows10 App using the MobileServiceClient library to handle login, logout etc.
    Until now everything is working fine.
    Now I am trying to build an ASP.NET MVC application that uses the same API described but is not deployed in the same App Service and also has another domain.
    Now the problem is that the MobileServiceClient for MVC lacks the extension methods that lets you log in against the API without an existing token. Instead it requires a valid token from Microsoft, Twitter etc. so I would have to implement the login myself again in the MVC app.
    This part is what I am trying to avoid.
    Also I would need new apps in the different login providers because the callback urls would be in different domains.

    So the question is: how can I use the API’s authentication mechanism from my MVC app (equal to W10 app)?

    Thanks,
    Andreas

  13. Please, correct me if I’m wrong:
    – the first time end-user uses my xamarin app (google authentication), he gets a token that will expire in 1 hour, after that, he finishes use my app and closes it.
    – Three hours later, he opens the app and tries to access data from an azure table (for example): in this case, now, his “old” token is expired so, using your code above, he gets a “new” refresh token and he is able to obtain his data from azure. Perfect.

    And now, what happens? will this new refreshed token expire in one hour like the first one?
    So, does he have to get a new one in 72-hours? And so on with the cycle?
    If not, “a fresh re-auth by the end-user will be required to get a new, non-expired authentication token”?

    Thanks for the article and the answer. I have some doubts 🙂

    1. Your understanding is correct. Refreshed tokens will have the same lifetime as the original tokens (1 hour in the case of Google). The tokens can be refreshed at anytime before or within the 72-hour window without requiring a re-auth. This will be a regular cycle within your app.

  14. failedRequest url=”https://TrackerTo:80/.auth/refresh”
    siteId=”664475180″
    appPoolId=”TrackerTo”
    processId=”9196″
    verb=”GET”
    authenticationType=”NOT_AVAILABLE” activityId=”{00000000-0000-0000-FE08-0080000000E9}”
    failureReason=”STATUS_CODE”
    statusCode=”403.80″
    triggerStatusCode=”403.80″
    timeTaken=”62″
    xmlns:freb=”http://schemas.microsoft.com/win/2006/06/iis/freb”

  15. Every time I re-read this blog post I learn something new. Very helpful.

    I have a couple of questions regarding custom authentication:

    1. You mentioned: “In particular, it does not scale well when large numbers of concurrent logins are expected and is incompatible with the local disk caching feature of App Service.”

    Do you mean concurrent logins on the device or at the server? And I admit I have no idea about local disk caching features. How limiting is this? Is the blob experiment still on the table?

    2. Does the whole easy local token storage work for custom authentication, or is it only for the supported Providers out of the box?

    I would like to add my own claims (for roles, etc.) and want to hit the database one time for role info and then add that to claims. I am already successfully creating my own tokens, but I don’t want to lose all the functionality that’s already built in for the supplied providers. The more I dig into this, the more cool stuff I find in the built in providers. Are there any other giant speed bumps coming that catch most folks when they try to do this?

    TIA

  16. I keep running into 401.71 errors (“You do not have permission to view this directory or page.”) for this line.

    App.MobileService.InvokeApiAsync(“/.auth/refresh”, HttpMethod.Get, null);

    wl.offline_access has been set for MS account auth.

    1. I am receiving this same error when trying to retrieve a refresh token using the same code. Has anyone found out the reason why, and a solution for it?

    2. 401.71 means authentication failed: either the token that was sent is invalid or no token was sent at all. In the former case, you can get more details by enabling Application Logging and taking a look at the application log output.

    3. I’m a little confused then – do we need a valid token to send the /.auth/refresh call to get a refresh token? If I had a valid token, then I wouldn’t need a refresh token. I’m sure I’m missing something though, and thank you for your response. Is there something in Azure AD I need to set up to retrieve this refresh token, and is there something else I need to put into the client app to retrieve it?

    4. This is what’s logged.

      2016-06-22T05:34:48 PID[12488] Verbose Received request: POST https://[dummy].azurewebsites.net/api/values
      2016-06-22T05:34:48 PID[12488] Information Sending response: 401.71 Unauthorized
      2016-06-22T05:34:51 PID[12488] Verbose Received request: GET https://[dummy].azurewebsites.net/.auth/refresh
      2016-06-22T05:34:51 PID[12488] Information Sending response: 401.71 Unauthorized
      2016-06-22T05:35:00 PID[12488] Verbose Received request: POST https://[dummy].azurewebsites.net/api/values
      2016-06-22T05:35:00 PID[12488] Information Sending response: 401.71 Unauthorized

    5. Carlo, check to make sure you’re actually sending an authentication token in your call to /.auth/refresh. If you were, you would have seen a warning indicating why the authentication failed.

      Greg, there are two possible cases: 1) you have a valid token. This is a valid use-case where you want to proactively refresh your tokens on a periodic basis. 2) you have a token which used to be valid, but expired in the last 72-hours. You can also use this token to attempt a refresh. Your client app should not need to retrieve this refresh token for any reason.

      If this is still not clear, post a question on StackOverflow, tag it with “azure-app-service”, and send me the link. That will make it easier to track.

    6. I’ve got to wait a bout an hour to test, but I think that’s what’s missing — no token was being sent.

  17. Great Article,

    Managed to set everything up using Azure AD but still encountering a problem with refreshing tokens.
    Our website communicates with another server, the authorization is done via adding an “Authorization” header to requests, those header contain “Bearer “.

    The problem is when I refresh the token store by calling “.auth/refresh” I only notice a change in ACCESS_TOKEN which is not used in this case.

    What am I doing wrong? Should I be using the access token when communicating with the remote server? Or should the refresh also change the ID token?

    Does the refresh action only change tokens when they are expired?

    Thanks!
    Niv

    1. Just to clarify:
      For authorization we use ID TOKEN in the header, but calling refresh only refreshes the ACCESS TOKEN. Even after the ID TOKEN has expired, refresh does nothing to it.

      Thanks

    2. Hey Niv, thanks for the feedback! Both the ID token and the access token should be getting refreshed. If possible, would you mind posting a question to StackOverflow and then sending me the link? It would be easier to investigate there vs. blog comments. One thing I’d like to know is how you’re checking to see whether the ID token has or hasn’t been refreshed (just to rule out testing issues). Thanks!

  18. I have a mobile app using AngularJS (ionic) and want to access WebAPIs on an Azure app service. For example, get from https://mysite.azurewebsites.net/api/Values. The app service has authentication turned on using Google provider. I’m able to do client-side auth and get the user’s Google access token on the mobile side. But when I pass this through on under the X-ZUMO-AUTH on my GET request, I still get an unauthorized error. Would you have some sample code on how to authenticate through app service with plain old javascript?

    1. Hi John. More documentation on our support for JavaScript clients can be found here: https://azure.microsoft.com/en-us/documentation/articles/app-service-mobile-html-how-to-use-client-library/#auth. But it sounds like what you’re doing should be correct. Try enabling Application Logging in the Azure portal to see whether there is more information available about the authentication errors. Otherwise I suggest posting a question on StackOverflow or the MSDN forums.

  19. Hi CGillum,

    Nice work on (and info about) the tokenRefreshExtensionHours.
    Is there a possibility to have the Azure Active Directory token have a sliding expiration? The refresh using Adal.js doesn’t work because the iframe gets blocked. And when it doesn’t (when I remove x-frame-options = none) my application still refreshes and users lose their work.

    Kind regards, Rick

  20. Hi CGillum. It is getting clearer – but I still need help de-fuzzing. (Wish there were some fully functioning repo w/ refreshing I could review… do you haz teh codez?) In your C# example, you call InvokeApi which I presume is calling some Controller in your Zumo app and it fails with Unauthorized. Is it failing because the zumo token is expired, or is it failing because the Controller tries to call Google and the Google token is expired? When you Refresh, are you refreshing the zumo token? the Google token? Both?

    1. Hi Tim. The Unauthorized result is because the zumo token (which I also refer to as the session token) expired. No Google API calls are involved in this case. Also, when you call /.auth/refresh, you’re refreshing BOTH the zumo token and the Google token.

      If you want a code sample which shows refresh, I have a post on Azure AD B2C that links to a demo page that’s written in pure HTML/JavaScript. I do token refresh using JavaScript in that demo page via a button click, so you should be able to view the source and see how it’s being done there.

    1. The setting can only be changed in Resource Explorer. You can find all the Easy Auth settings under https://resources.azure.com/subscriptions/{subscription}/resourceGroups/{resource-group}/providers/Microsoft.Web/sites/{site-name}/config/authsettings/list. Right now, tokenRefreshExtensionHours is not visible by default, so you would need to add it as a new JSON field.

  21. cgillum,

    Thanks for a great thread.

    I am stumped at the moment with something crazy – really wonder if you could shed some light on it!

    I have Azure Mobile App setup to use Authorization and NOT use an outside provider – I am doing my own auth. I have selected the Token Store to be ON inside the Azure Mobile App, and I have selected “Allow request (no action)”. No authentication providers have been configured.

    On the server side, I have a custom API (un-protected), and used to get a token, with this code:

    public static JwtSecurityToken GetAuthenticationTokenForUser(string email)
    {
    var claims = new[]
    {
    new Claim(JwtRegisteredClaimNames.Sub, email)
    };
    var signingKey = Environment.GetEnvironmentVariable(“WEBSITE_AUTH_SIGNING_KEY”);

    var audience = ConfigurationManager.AppSettings[“ValidAudience”];
    var issuer = ConfigurationManager.AppSettings[“ValidIssuer”];

    var token = AppServiceLoginHandler.CreateToken(
    claims,
    signingKey,
    audience,
    issuer,
    TimeSpan.FromDays(14600) //FromHours(24) // 40 years (basically never expires)
    );

    return token;
    }

    For testing purposes, I’m just using a vast expiration date (I know it’s bad practice but I’m trying to solve this problem! … 😉

    This duly creates the token and I return it back to the client (Xamarin Mobile App) as a string…

    Then on the mobile side, on the MobileClientService, I use the token like this:

    var mobileServiceUser = new MobileServiceUser(result.Id);
    mobileServiceUser.MobileServiceAuthenticationToken = result.Token;
    App.RpatsMobileClient.ClientService.CurrentUser = mobileServiceUser;

    On subsequent calls to .PushAsync etc to a controller on the server, the token is coming through on the header, but I keep getting an Unauthorised response (on my protected controllers, decorated with [Authorize].

    I trapped it on the server in one of my protected controllers, with code like this:

    protected override void Initialize(HttpControllerContext controllerContext)
    {
    base.Initialize(controllerContext);

    var test = (ClaimsPrincipal)User;

    DomainManager = new EntityDomainManager(DbContext, Request);
    }

    When I examine “test”, and the IdentityProperty, I get an ImpersonationLevel of “Anonymous”.

    But the header is populated with X-ZUMO-AUTH which contains the correct token…

    It seems like the Azure app just refuses to acknowledge the token for some reason, and give me a proper user back…

    The funny thing is, if I run this exact same server LOCALLY, it all works fine…it just refuses to work inside Azure…

    It almost feels like Azure is not storing the token when I call

    var token = AppServiceLoginHandler.CreateToken(

    on the server?

    What am I missing?

    Your help would be greatly appreciated, it’s driving me insane! … 😉

    1. Sorry for the trouble Barry. I recommend enabling Application Logging to see why the token is being rejected. My intuition says it could be something related to audience validation, but the application logs should tell you exactly what’s wrong.

  22. Ok I am using this from the Cordova plugin. When you login interactively that gives you an id_token which you can pass to /.auth/me to get an access_token. That works great. When I call /.auth/refresh, I get another access_token and that works great. Except that it requires an id_token on the XUMO header right? Won’t that have long expired.

    Finally, the piece I am trying to figure out is automatic login of the MobileServiceClient object when you call client.login(‘aad’, { accesss_token: myAccessToken }). I’ve done a lot of testing and that expects an id_token and not an access_token to work. Therefore, the token I get from refresh doesn’t work. Is there another way to get my client object to recognize the user is logged in. Do I manually create a currentUser object and assign the access_token and username?

Leave a Reply