App Service Auth and Azure AD B2C (Part 2)

This post is a continuation of my previous post on App Service Auth and Azure AD B2C, where I demonstrated how you can create a web app that uses Azure AD B2C without writing any code. If you haven’t done so already, be sure to read that post to get proper context for this one.

In a recent service update, we’ve improved our overall support for B2C in Azure App Service. This includes enhancing our existing web app support, but more importantly includes adding full support for leveraging B2C in mobile, API and function apps. More specifically, support has been added for the Easy Auth Token Refresh API. Additionally, the Login API has been updated to support specifying specific B2C policies as arguments. If you’re a Mobile app developer, these improvements will make using Azure AD B2C in your mobile app significantly easier.

This post will go into more details about these improvements, show a few code snippets, and conclude by demonstrating these B2C capabilities in a simple demo web app.

Pick Your Policy

Specific B2C policies can be invoked using the built-in Easy Auth login API for AAD. If you’re not familiar with the Easy Auth login API, it works by allowing you to initiate a server-directed login by sending a GET request to your web, mobile, API, or function app’s built-in {root}/.auth/login/aad endpoint. This endpoint supports the standard sign-in query string parameters for AAD, including the newly added p={policy} query string parameter which allows you to specify a B2C policy by name.

For example, one could use the following HTML in a web app to create hyperlinks that invoke specific B2C policy workflows, such as editing the user profile or resetting the password:

<a href="/.auth/login/aad?p=B2C_1_EditProfile&post_login_redirect_uri=/">Edit Profile</a>
<a href="/.auth/login/aad?p=B2C_1_ResetPassword&post_login_redirect_uri=/">Reset Password</a>

Clicking one of these links will automatically redirect the user to the corresponding B2C policy page and allow the user to edit their user profile or reset their password accordingly.

If you’re writing a native client which uses one of the App Service Mobile Client SDK flavors, you could write something similar in platform-specific code. The example below shows how a mobile client app written in C# can invoke a B2C sign-in policy that requires MFA:

  new Dictionary<string, string>
    { "p", "B2C_1_SignInWithMFA" }

In this case, the user will presented with a native web view dialog which allows the end user to sign in using MFA (phone authentication, etc.). The primary thing to keep in mind about this experience is that these B2C policies can be easily invoked with just a few simple lines of client-side code. No platform-specific middleware or server-side code is required.

One important note of caution: the claims associated with the signed-in user will be updated every time you invoke a B2C policy. If your app depends on the presence of specific claims, make sure they are explicitly configured in each of your B2C policies.

Refreshing Tokens (Optional)

Easy Auth also has a built-in API for refreshing both provider-specific OAuth tokens and the app-specific authentication tokens. It works similar to the login API, in that it requires a GET request to the app’s built-in {root}/.auth/refresh endpoint.  More information on token refresh (and our token management story all-up) can be found in my earlier App Service Token Store blog post.

This token refresh support also extends to Azure AD B2C apps and is completely optional. However, leveraging token refresh is very important if you’re building a native app to ensure a smooth user experience. In order to set this up, you will need to do the following:

Create an app key for your B2C application

Creating app keys can be done in the Azure management portal for B2C.

Generating an App Key in the B2C Management Portal
Generating an App Key in the B2C Management Portal

Make a note of the app key that gets auto-generated by the portal. We’ll need it to configure Easy Auth in the next step.

Update the Easy Auth Settings

Easy Auth doesn’t require an app key by default and instead relies on the OpenID Connect Implicit Flow to implement secure logins. In order to get refresh tokens, however, we need to switch to the Hybrid Flow (Don’t worry if you don’t understand what these mean, Easy Auth will take care of the protocol details for you).

To make this protocol switch, you need to update the App Service Auth settings for your app with the key from the previous step. Unfortunately there is no official UI to assist with this yet (we’re actively working on it). Until we get around to building that UI, I usually recommend that people use Azure Resource Explorer. First, navigate to your web app in the Azure Portal (you may need to switch tenants in the upper right-hand corner if you’re still on the B2C management page). You can then navigate to Resource Explorer by using the Resource Explorer link in the Tools section of the portal, like in the screenshot below.

Finding the Resource Explorer link for your app
Finding the Resource Explorer link for your app in the Azure portal

From there, you can use your app key to configure the client secret property of your auth settings. Making this change requires the following steps:

  • Under your site node, navigate to /config/authsettings.
  • Click Edit to enable making changes.
  • Set clientSecret (a string property) to the app key value that was generated in the Azure AD portal.
  • Set additionalLoginParams (a JSON array of strings) to ["response_type=code id_token"].
  • Click the Read/Write button at the top of the page to enable making changes.
  • Click the PUT button to save your changes.

Here is a screenshot illustrating what this will look like:

Setting the app’s client secret and default login parameters using Azure Resource Explorer
Setting the app’s client secret and default login parameters using Azure Resource Explorer

Once this is done, all future logins should result in refresh tokens in the app’s built-in token store. You can then write client code which invokes the {root}/.auth/refresh API (or use the corresponding Mobile Client SDK method) to periodically refresh these tokens, which allows your app to function for longer periods of time without requiring a re-auth.

Demo App

To demonstrate all of this, I’ve created a single-page application (aka a SPA app) written using HTML, jQuery, and Bootstrap. It’s a trivial app written by someone who is clearly not a UI designer (me) and demonstrates the various patterns described in this blog post.  You can browse to it here and play around with it (I promise not to give out your information if you decide to provide it), or simply copy the source code and host it yourself in your own App Service web app. Note that I theoretically could have also built this using the iOS, Android, UWP/Xamarin, or one of the other mobile SDKs that are provided, but it was simpler for me to build a plain-old HTML web app. 🙂

The important thing to keep in mind is that there is absolutely no auth code in this sample (in fact, no backend code at all). All of this is implemented on the client and in the App Service platform with the help of Azure AD B2C. No SDKs required.

When you first visit the demo page, you will be given two login options. One is a standard email-based login and the other is an MFA login which requires you to register a phone number for phone authentication.

Starting page when unauthenticated
Demo app starting page when unauthenticated

The phone authentication provided by B2C allows you to do phone calls or SMS in my case. You can enter the provided code to complete the authentication.

Phone authentication
Phone authentication when using Azure AD B2C

Once signed-in, you will see a few B2C policy actions that you can invoke as well as a set of user claims displayed on the page. There’s also a sign-out button which uses Easy Auth’s built-in Logout API to clear the session.

Policy Actions
This B2C demo app supports updating the user profile and resetting the password used for logging in.
B2C Claims
This B2C policy is configured to return the object ID, postal code, name and email address.

Note that one of the claims,, contains the name of the B2C policy that the user logged-in with. Your application code can take advantage of this if, for example, you want to grant special permissions to users who log in using a higher-privilege B2C policy.

Again, it’s a very simple app to quickly demonstrate some of the powerful capabilities of the App Service “Easy Auth” platform when combined with Azure AD B2C.  My hope is that this is enough to give you some ideas about how you can leverage the Azure AD B2C platform in your own App Service apps.

Following Up

Have a technical questions about Azure App Service and/or Azure AD B2C? Head over to and tag your questions with azure-app-service and/or azure-ad-b2c accordingly. We monitor posts with these tags and are happy to help.

App Service Auth and Azure AD Domain Hints

When creating web, mobile, API, or Function apps for use by members of your organization, it’s often the case that you’re using Azure Active Directory and you want to remove the option to log in with non-organizational credentials. For example, you want to prevent users from accidentally logging in with MSA credentials (,,, etc.). This can be done by leveraging what’s known as a domain hint when navigating users to the Azure AD login page.

Domain hints will do two things for you: 1) remove the home realm discovery page from the login flow and 2) ensure that users can’t accidentally auto-log into your app using wrong credential types (for example, MSA credentials). More background information on Azure AD’s support for domain hints can be found on the Microsoft Enterprise Mobility blog:

Vittorio Bertocci also talks about domain hints in his post on Skipping the Home Realm Discovery Page in Azure AD., demonstrating how to use them when using ADAL and the OpenID Connect Middleware to build your web app. In this post, however, I’ll describe how enable domain hints when using App Service’s integrated Easy Auth feature.

Default Login Parameters

Most web apps will want to configure domain hints to be used for all logins. Unfortunately you cannot configure default domain hints in this way using the Azure portal today. Instead, you must use the App Service Management API. Until we get around to building a portal experience, I recommend that most people configure default domain hints in Azure Resource Explorer. This can be done using the following steps:

  1. Search for your web, mobile or API app using the search bar. Alternatively, you can navigate directly to your app if you click on the Resource Explorer link in the tools section of the portal.
  2. Under your site node, navigate to /config/authsettings.
  3. Click Edit to enable making changes.
  4. Set additionalLoginParams to the following (This is a JSON array value): [""]
  5. Click the Read/Write button at the top of the page to enable making changes.
  6. Click the PUT button to save your changes.

The JSON configuration for your auth settings should look something like the screenshot below. In my case, I specified since the app shown here is intended to be used by Microsoft employees.


Once this is done, users will no longer see the home realm discovery page when logging into the app. Instead, users will be immediately directed to the organizational login page, ensuring they cannot intentionally or accidentally log in with the wrong credentials.

Using the Login API

If you’re building an app that invokes the built-in /.auth/login/aad REST API, you can alternatively specify domain_hint={domain} as a query string parameter to get the same effect.

For example, if I’m writing a mobile client and using the App Service .NET SDK, I could write the following code to initiate a login using a domain hint for

var user = App.MobileClient.LoginAsync(
  new Dictionary<string, string>
    { "domain_hint", "" }

Similarly, I could create a login link in a web page using HTML that includes a domain_hint parameter.

<a href="/.auth/login/aad?">Login</a>

This allows me to specify login hints without changing the auth settings of the app as I showed in the first part of this post. In theory, this would also allow me to create multiple login links, one for each domain that my Azure AD application supports. Note that if an app is already configured with a default domain hint, the query string parameter will override that default.


In conclusion, most single-tenant applications will want to use domain hints to optimize the login experience. These hints allows you to skip the home realm discovery page in the Azure AD login sequence and mitigates the common problem where the browser will try to log into the app using MSA credentials via SSO. Depending on the type of application you are building, you can use either the default login parameter method or you can explicitly specify login hints via the built-in /.auth/login/aad endpoint.

Creating a Corporate Wiki in Azure

Using Azure App Service and Azure Active Directory (AAD), it’s possible to create a MediaWiki-based web app for use within your organization with minimal setup and for little or no cost. If you’re not familiar with MediaWiki, it’s the same open source platform which powers Wikipedia. A few folks within Microsoft surprised me when they created internal wikis using my Easy Auth feature (Authentication / Authorization) so I thought I’d try it out for myself and do a quick write-up on it.

Note that I’m assuming you’re already familiar with Azure Active Directory and that you have an Azure Subscription that is associated with your organization. If not, you can find more information here:

Creating a Web App

The first step is to create a new web app. If you already know how to do this, you can skip this section. The easiest way is to simply navigate to, log in with your Azure Subscription (the one for your organization), and go to New –> Web and Mobile –> Web App. This can also be done using the Azure PowerShell or Cross-Platform CLI Tools, though I won’t cover those details here. In this example, let’s suppose you named the web app easyauth-wiki (all my examples and screenshots will use this name, but you can replace it with your own app name).

IMPORTANT: If you want to create custom hostnames for your web app, you should set that up now.

Enabling AAD Authentication

As I hinted to before, this can be done in the portal via Easy Auth, Azure App Service’s integrated authentication feature. For simplicity, we’ll use the Express configuration, which automatically creates an AAD application and configures it for your site.

  • In, select the web app you previously created.
  • Select Settings and navigate down to Authentication / Authorization.
  • Set App Service Authentication to On.
  • Under Authentication Providers, select Azure Active Directory
  • For Management mode, select Express and then click OK.
  • Back in the Authentication / Authorization blade, click Save.

Enable AAD Authentication

At this point, your new web app is now protected using Azure Active Directory authentication and only users in your organization will be able to access the site.

Installing MediaWiki

It’s possible to create a MediaWiki app using the Marketplace gallery in the Azure management portal, but for this write-up I’m going to configure it from scratch. This also allows me to use a local SQLite database (instead of paying for a ClearDB MySQL database), which is convenient for testing and is free. If you’re expecting your wiki to be used by a large number of users, then you should definitely consider using MySQL instead of SQLite, though I won’t cover the MySQL setup here.

Download MediaWiki

There are multiple ways to get MediaWiki installed on your web app. I’m going to show you the quick-and-dirty way which doesn’t involve any 3rd party tools or source control. Start by navigating to the debug console on the SCM endpoint for the site you just created: https://{appname} You can log in using your Azure Subscription credentials if you’re not already logged in. Then do the following:

  • cd D:\home\site\wwwroot
  • del hostingstart.html
  • curl > mediawiki.tar.gz
  • tar -xzvf mediawiki.tar.gz

The last step might take a while due to the large number of files to extract. This will get all the MediaWiki bits onto your web app. I chose MediaWiki 1.26.3 since that was the latest when I started writing this post, but a newer version is probably available by the time you read this (in fact, 1.27.0 was released shortly after I finished putting together my sample). You can find available versions of MediaWiki on the MediaWiki download page. Be sure to adjust my instructions accordingly depending on which version you decide to use.

Configure MediaWiki

Now that MediaWiki is installed, let’s configure it with a simple SQLite database backend.

  • Navigate to https://{appname}
  • Click through the first two pages.
  • In the Connect to database page, select Database type: SQLite and click Continue.
  • Configure your wiki with a name and an administrator account and click Continue.
  • For User rights profile, select Private wiki.
  • Feel free to mess with additional settings on this page as necessary. Under Advanced configuration, you may want to enable PHP object caching for improved performance (internally we use WinCache). When all done, click Continue and then Continue two more times to complete the installation.

At this point, you should see a Complete! screen and a LocalSettings.php file should have been downloaded by your browser. You’ll need to upload this file to your MediaWiki installation directory (D:\home\site\wwwroot\mediawiki-1.26.3) to complete the installation. The easiest way is to simply drag/drop it from your file system to the browser window which shows the Debug Console in the D:\home\site\wwwroot\mediawiki-1.26.3 directory.

Configuring Integrated Authentication

The final required step is to connect the user accounts in your Azure Active Directory to the user accounts in your wiki. This can be done using the Auth_remoteuser extension, as I’ll describe here. The great thing about this extension is that it can also be used for on-premises Active Directory, making it very easy to do on-premises to Azure migrations.

Once again, let’s take the simple route of installing it directly onto the web app using the Kudu Debug console (otherwise you can follow the instructions on the extension page).

  • Use cURL to download the extension, e.g. curl > Auth_remoteuser-REL1_26-6103d19.tar.gz (the actual URL will be different for you depending on which version is the latest by the time you read this).
  • Extract the downloaded extension into the MediaWiki extensions directory – e.g. tar -xzvf Auth_remoteuser-REL1_26-6103d19.tar.gz -C D:\home\site\wwwroot\mediawiki-1.26.3\extensions (again, your exact path may differ).
  • Open your LocalSettings.php for editing (e.g. D:\home\site\wwwroot\mediawiki-1.26.3\LocalSettings.php) and make the following changes:
require_once "$IP/extensions/Auth_remoteuser/Auth_remoteuser.php";
$wgAuth = new Auth_remoteuser();

At this point your identity setup is now complete! MediaWiki automatically recognizes your login. No registration required. You can test it by browsing to the root of your MediaWiki installation – e.g. https://{appname}

The last step is to add a URL rewrite rule to fix your URLs so that you don’t need to include the MediaWiki installation directory in your URL.

Configuring URL Rewrite Rules (Optional)

The final step involves configuring IIS rewrite rules on your app to remove the installation directory as well as to “prettify” your URLs. Without doing this, your URLs are quite ugly and hard to discover.

Ugly URL

There are many ways to configure this so consider the below just one of many examples.

  • In the Kudu console, navigate to D:\home\site\wwwroot.
  • Create a web.config file by entering the following command: touch web.config
  • Open the file for editing and add the following content (replacing the MediaWiki version numbers as necessary):
<?xml version="1.0" encoding="utf-8"?>
    <rule name="wikiRule1" stopProcessing="true">
     <match url="^wiki/(.*)$" />
     <action type="Rewrite" url="/mediawiki-1.26.3/index.php?title={UrlEncode:{R:1}}" />
    <rule name="wikiRule2" stopProcessing="true">
     <match url="^wiki/$" />
     <action type="Rewrite" url="/mediawiki-1.26.3/index.php" />
    <rule name="wikiRule4" stopProcessing="true">
     <match url="^/*$" />
     <action type="Rewrite" url="/mediawiki-1.26.3/index.php" />
  • Open the LocalSettings.php file and ensure the following variables are set as shown here (again, you may need to fix up the MediaWiki version number):
$wgScriptPath = "/mediawiki-1.26.3";
$wgArticlePath = "/wiki/$1";
$wgUsePathInfo = true;

Now, if you navigate to your site root, you’ll get redirected to https://{appname} and you will see your wiki content. If you click on a page, you’ll get a friendly /wiki/PageTitle URL.

Pretty URL

This is a big improvement from before!

Linking to Anchors (Optional)

It’s common for people to create links to certain sections of their wiki pages which contain URL fragments. For example, you might have a URL which looks like /wiki/Main_Page#SectionZ. This ensures that when you share the link with someone and they click it, the browser will automatically scroll to wherever “SectionZ” is located on the page. More information on anchors in MediaWiki can be found here.

There is one problem that occurs when you introduce login to your web app, however. If you’re familiar with URL fragments (the #SectionZ part of the URL) then you’ll know that they are never sent to the server. By default, the Easy Auth module handles the login entirely on the server, so if one of your colleagues clicks on a link to the wiki with a URL fragment in it and they are not yet logged in, the URL fragment will be lost by the time they finish logging in and get redirected back to the page they tried to visit. This is a pain because then they have to manually scroll to find the location that they were supposed to be directly linked to. Note that this problem is not unique to MediaWiki or Easy Auth. There are many other server-side authentication solutions which suffer from the same issue.

One potential workaround is to have people complete the login and then click the link again in order to be navigated to the correct location in the target page. Obviously, this is not a very good solution. Several teams internally at Microsoft have run into this problem and reported it to me, so I thought it would be a good idea to find a way to solve it in a way that didn’t require users to know about the problem. To that end, we recently added a new feature in Easy Auth which solves this by using some JavaScript to ensure URL fragments are correctly preserved. Currently it’s an opt-in feature which you can enable by setting the WEBSITE_AUTH_PRESERVE_URL_FRAGMENT app setting to true in the Azure management portal.

Preserving URL fragments in login

With this setting in place, when users click on your links which contain URL fragments, the login process will ensure that the URL fragment part of your URL does not get lost in the login redirect process. Let us know in the comments if you found this feature helpful for you, we’d love to know about it. If it helps out enough folks, we’ll likely turn on this capability by default.

App Service Auth and Azure AD B2C

An exciting new preview feature which was recently added to Azure Active Directory is Azure Active Directory B2C. “B2C” stands for “Business to Consumer” and allows a developer to add user and login management to their application with very little (if any) coding. This also includes login integration with social identity providers like Facebook, Amazon, LinkedIn, etc. Check out their documentation and blog posts for more details. My colleague Swaroop from the Azure AD team also has a nice //build video where you can see it in action.

From my perspective, App Service Authentication / Authorization (Easy Auth) shares a similar goal of B2C, which is to make it really easy to build identity into your application. We saw a great opportunity to make these features work well together, giving you both an identity management system as well as login and OAuth token management without requiring a single line of code.

In this post, I’ll describe how you can use Easy Auth to add Azure AD B2C capabilities to your App Service Web App.

Creating an App Service Web App

Hopefully you know how to do this by now. Go ahead and create a web app (or an API/mobile/function app – they all work the same way) and make a note of the URL. For example, when drafting this blog post and walking through the steps, I created Use your own web app URL in place of mine wherever you see it in these instructions. However, don’t configure Authentication / Authorization yet. We’ll do that in a later step.

Creating the Azure AD B2C Tenant and Application

We don’t currently support an “Express” setup of B2C like we do for classic Azure AD, so these steps will need to be done manually. You can find detailed instructions for this below:

  1. Create an Azure AD B2C tenant
  2. Register your application

Note that in step 2, you’ll need to use the https address of the web app you previously created as the Reply URL and you must suffix it with “/.auth/login/aad/callback” (again, in my case this is Once this is done, you should have an application in the B2C portal which looks something like the following:

B2C Application Blade

Make a note of the Application Client ID that you see in the Application blade. You’ll need this in a later step.

Adding a Sign-Up/Sign-In Policy

For simplicity, we’ll create a single B2C “policy” which allows the user to sign in or sign up if they don’t already have an account. In the portal, this is the Sign-up or sign-in policies selection. Add a new policy (assuming you don’t have one already). The details of the policy don’t matter too much, so I won’t provide any specific guidance here. There are a lot of options, including whether to configure social identity providers. In my case, I set up email login as well as Google and Facebook. To get started quickly, I suggest you use the email sign-up policy. When you’re done, make a note of the Metadata Endpoint for this policy URL which gets generated, like in the screenshot below:

B2C Policy Blade

Azure AD B2C supports other policy types as well, but the combination sign-up/sign-in is currently the one best suited for Easy Auth login integration.

Configure Easy Auth

Now let’s go back to the web app we previously created. We’ll configure Easy Auth with Azure AD using the Advanced configuration option. The steps are:

  1. In the portal in the context of your web app, click the Settings icon.
  2. Set App Service Authentication to On
  3. Configure Azure Active Directory
  4. Select the Advanced management mode
  5. Set the Client ID to be the Application Client ID from before.
  6. Set the Issuer URL to be the Metadata Endpoint for this policy URL value that was generated from your sign-in/sign-on B2C policy.
  7. Click OK and then the Save icon to save your changes.

Your Authentication / Authorization settings blade should look something like the following:

Authentication / Authorization Blade

Now if you navigate to your site, you should see the B2C login page that you configured previously. Depending on how it was configured, you can sign up using social identity credentials or you can sign up using username (or email) and password. You will also be prompted for additional registration information, such as your name, etc (again, all dictated by the policies you configured).

Here is an example of what your initial sign-in page might look like. Notice the link on the bottom of the image which allows users to register:

B2C Login Page

Below is an example of what your “sign-up” registration page will look like. If you selected the email option, Azure AD B2C will even implement the email verification workflow for you.

B2C Sign-Up Page

That’s it! You’ve now created a skeleton B2C web application that allows users to sign-up and sign-in without writing any code or deploying any databases! I’ve used all the defaults in terms of styling, but Azure AD B2C does allow you to customize the look and feel of these pages to match your own application branding, if you choose. See the B2C UI customization documentation for more information.

Once signed in, you can write code which inspects the inbound HTTP headers and/or the /.auth/me endpoint (both described in my earlier Token Store post) to get more information about the user. If you’re running an ASP.NET application, you can also enumerate the claims on the current ClaimsPrincipal. Specifically, you should be able to see all the claims that you configured in your B2C policy. This is great because you don’t need to provision your own database which contains this information – it’s built into the B2C directory and can be accessed using the features of Easy Auth.

Azure AD B2C Social Providers vs. Easy Auth Social Providers

One thing you may have noticed is that there are now two ways to incorporate social logins into your web app: using B2C policies or configuring them directly in the Authentication / Authorization settings. Ideally, there would be just one which is common between the two technologies. Unfortunately we’re not there yet. Until then, here are some important differences between social providers in Azure AD B2C and Easy Auth:

  • Different identity providers: B2C and Easy Auth support different providers. At the time of writing, B2C supports MSA, Facebook, Google, LinkedIn, and Amazon identities. Easy Auth, however, supports MSA, Facebook, Google, and Twitter.
  • Client-Directed Login: Both B2C and Easy Auth support server-directed social logins where the login flow is controlled by the browser. However, only Easy Auth supports client-directed logins where the login flow is controlled by the client operating system (typically a mobile OS or a JavaScript client).
  • User Claims: B2C provides a somewhat normalized set of user claims for each login. These claims are similar to what you’d see in an ordinary AAD login. The claims are also configurable. With Easy Auth, however, the claims are static and in many cases are different for each identity provider.
  • OAuth Tokens: With Easy Auth, the application code has direct access to the provider-specific OAuth tokens. This is useful if you want to make graph API calls on behalf of the logged-in user (for example, calling the Facebook Graph to post a photo to the user’s timeline). B2C, however, does not expose the provider OAuth tokens to your application code.

If social identity integration is important to your app, then consider these differences very carefully when deciding between the two options. Note that these limitations will certainly change as both Easy Auth and Azure AD B2C evolve over time, hopefully in a way that better aligns them together (this is certainly our goal, internally).

Taking it to the Next Level

This post demonstrated using a single, global B2C policy within a web app in a way that doesn’t require any code or database setup. If you are a mobile, API, or SPA app developer, I have written a followup post which goes into more details about how to use code to dynamically select B2C policies, how to set up token refresh, and even included a sample SPA app which demonstrates these capabilities. Check it out in Part 2 of the App Service + Azure AD B2C series.

App Service Auth and the Azure AD Graph API

This post demonstrates how an App Service Web, Mobile, or API app can be configured to call the Azure Active Directory Graph API on behalf of the logged-in user. If you haven’t read it already, this post extends from my previous one on the Azure App Service Token Store.


The default setup for Azure AD that we use does not include the configuration required for your app to call into the Graph API. However, there are a couple one-time configuration changes that you can make to enable this. In the future, we plan to make this as simple as clicking a button or checkbox in the portal, but until that happens, there is some additional setup required.

Step 1: Update Azure AD Configuration in Azure AD Portal

You can find and manage your Azure AD application in the legacy Azure Portal at If you used the Express setup when configuring Azure AD on your App Service app, you can search for your Azure AD app using either your app name or the client ID of your Azure AD application. Once there, you will need to make two changes: 1) add the “Read directory data” delegated permission and 2) add a key to your Azure AD application.

enter image description here

If your app is already configured with the “Read directory data” and already has an existing key, then no further changes are necessary.

Step 2: Update App Service Auth Configuration via REST API

Next you need to update the App Service Auth settings for your web, mobile, or API app with your Azure AD key plus some additional login parameters. This is a little tricky because there is no official UI to assist with this. Until we get around to building that UI, I usually recommend that people use Azure Resource Explorer, using the following steps:

  • Search for your web, mobile or API app using the search bar.
  • Under your site node, navigate to /config/authsettings.
  • Click Edit to enable making changes.
  • Set clientSecret (a string property) to the key value that was generated in the Azure AD portal.
  • Set additionalLoginParams to the following:

(This is a JSON array value)

["response_type=code id_token", "resource="]
  • Click the Read/Write button at the top of the page to enable making changes.
  • Click the PUT button to save your changes.

The JSON configuration for your auth settings should look something like the screenshot below.

enter image description here

Once this is done, the next time users log into your web app, there will be a one-time prompt to consent to graph API access. Once consented, the App Service Auth infrastructure will start populating access tokens and refresh tokens into your app’s Token Store, which can be used for making Azure AD Graph API calls.

Calling the Graph API as the End-User

Once the app is properly configured, the code to obtain the token and call into the Azure AD Graph API using the user’s identity is relatively trivial. Here is a C# example of how to obtain the user’s profile photo from the Azure AD Graph from within your Web, Mobile, or API app:

// The access token can be fetched directly from a built-in request
// header! If this is null, it means you either haven't completed
// the setup prerequisites or you have disabled the token store in
// the Azure portal.
string accessToken = this.Request.Headers[

// Call into the Azure AD Graph API using HTTP primitives and the
// Azure AD access token.
var url = "";
var request = WebRequest.CreateHttp(url);
var headerValue = "Bearer " + accessToken;
request.Headers.Add(HttpRequestHeader.Authorization, headerValue);
using (var response = request.GetResponse())
using (var responseStream = response.GetResponseStream())
using (var memoryStream = new MemoryStream())
  string encodedImage = Convert.ToBase64String(

  // do something with encodedImage, like embed it into your HTML...

The above example is intentionally trivial, but you could imagine customizing it to use other Azure AD Graph APIs, including group membership APIs for building your own security group ACLs. I’ll also point out that I used HTTP primitives rather than using the official Graph API Client SDK. This was mainly to emphasize that access to the Azure AD Graph API can be written in any language and doesn’t require any SDKs (though you can certainly use the SDKs if you like).

If you’d like more information on the available Azure AD Graph APIs, please consult the documentation on MSDN: If you have any questions or are running into issues, I recommend posting them on StackOverflow and adding the tags azure-app-service and azure-active-directory. Also, be sure to reference this post in your question. I hope this is helpful!

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


Facebook Token Request Headers


Google Token Request Headers


Microsoft Account Token Request Headers


Twitter Token Request Headers


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:

  "user_id": "<user_id>",
  "user_claims":[{"typ": "<claim-type>","val": "<claim-value>"}, ...],

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

Here is an example snippet in C#:

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

  // 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.

Architecture of Azure App Service Authentication / Authorization

Authentication / Authorization (which I’ll refer to as Easy Auth throughout this post) is a feature of Azure App Service that allows you to easily integrate a variety of auth capabilities into your web app or API. It’s built directly into the platform and doesn’t require any particular languages, SDKs, security expertise, or even any code to utilize. This is why we call it easy – anybody can leverage it, even non-developers, with just a few clicks in the management portal.

In this post we will look at how Easy Auth is built and the various design tradeoffs involved. Be warned: We’ll go into deep technical detail in this post. If instead you’d like to learn more about what this feature is at a high level and how to use it, take a look at our overview topic in the Azure documentation and/or this recent announcement by my colleague Matthew Henderson. Otherwise, continue reading.


Easy Auth is implemented as a native IIS module that runs in the same sandbox as your application. When enabled, every HTTP request dispatched to the IIS worker process must first pass through this module before your application code has a chance to react.

Easy Auth Runtime Architecture
The internal runtime architecture of an App Service application that runs the Easy Auth IIS module (click to enlarge).

As you can see, the module runs in the same sandbox as your application, but is still very much separate from your application. It’s automatically injected when enabled via the management portal. No SDKs, specific languages, or any code changes are required. It is configured using environment variables, which are internally populated by the portal (or the Azure Resource Management REST APIs).


The do-it-yourself way to accomplish this could have been to use include your favorite auth middleware directly into your application code. As a developer, this gives you a lot more control, but requires more work and requires you to know what you’re doing (OAuth 2, OpenID Connect, cookies, encryption, HMACs, CSRF, replay-attacks, etc.), which can be scary if it’s security-related. The reality is that some people don’t want to have to think about these things. Why not have the platform take care of it for you?

Another logical way to achieve the same outcome could have been to leverage an authentication proxy which sits in front of your app. You may have even seen some Microsoft products which do this, such as API Management or the preview versions of API and Mobile apps (i.e. those prior to November 2015) which deployed separate Gateway web apps. However, it was decided that this approach is not ideal for the most common types of application backends.

Platform Integration

The best part of incorporating the authentication layer directly into the platform is that it can integrate very nicely with the platform. This ultimately benefits you, the customer, in a variety of ways. A few examples:

  • Integrated Identity: If you’re writing an ASP.NET app, you can access the identity and claims associated with the authenticated user using the ClientPrincipal.CurrentPrincipal API. Web API attributes such as [Authorize] also work natively. Even PHP apps benefit because we automatically set the REMOTE_USER server variable, allowing PHP apps to infer the identity of the user. This is huge for easily enabling you to do things like creating corporate MediaWiki apps (something we do internally at Microsoft).
  • Logging: If you’re using the Application Logs feature of App Service (which is an awesome feature, by the way), you’ll notice that Easy Auth traces are included directly in your application traces. If you see an authentication error that you didn’t expect, you can conveniently find all the details by looking in your existing application logs.
  • Error Tracing: For more advanced debugging, you enable Failed Request Tracing in your application. Because Easy Auth is an IIS module that runs in-process with your app, you can see exactly what role it might have played in a failed request. Just looks for references to a module named EasyAuthModule_32/64. Auth middleware, on the other hand, does not have this advantage because IIS can’t distinguish it from your application code.
  • File System Storage: If you have the Easy Auth Token Store enabled, we can cache OAuth tokens directly on disk rather than needing to provision and manage a separate storage account. I’ll talk more about the token store in a future post.
  • Configuration: All Easy Auth configuration is surfaced to the application as app settings. This is useful because your application code can easily read these settings. Take a look at the Kudu environment page to see them for yourself – all Easy Auth settings are prefixed with WEBSITE_AUTH_. This also makes it easier for us to expose experimental features that you can turn on using app settings.
  • Updates: New features and improvements can be added to your app without requiring you redeploy any part of your application.

There may be other benefits that I’ve missed, but I think you get the basic idea of why we decided on this integrated approach to authentication in App Service.


In terms of performance, the goal of Easy Auth is to ensure that the overhead of this feature is non-noticeable and/or an improvement over alternative authentication solutions. This design is already an improvement over gateway-architectures simply because there is no additional network hop between clients and your application. The Easy Auth module runs in-process with the application host (w3wp.exe).

In terms of the code itself, Easy Auth is actually built using mostly managed code. The attentive reader may have noticed that I said this is a native module earlier in this post, and it still is. However, the native layer is just a small shim between IIS and the core module implementation. What this means practically is that we can engineer an IIS module in .NET without taking a dependency on ASP.NET and System.Web. This is important because traditional managed modules (or more specifically ASP.NET) can incur a relatively heavy performance penalty which serves no benefit when hosting non-ASP.NET applications (PHP, Node.js, etc.).

Wrapping Up

Hopefully this information is useful, interesting, or both. 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.