Share via


Azure AD B2C - Kicking it up a notch with support for AAD as IdP

I have mentioned AAD B2C before, and it should be your go-to feature if you want to have users logging in to your apps with their "social" identity. Like all Azure services B2C also evolves, and there happens to be a newly released feature I would like to highlight :)

While B2C covers the big platforms like Google and Facebook it's no surprise that one of the major questions developers have is "does it support the Identity Provider I want to use?". Which is a fair question. Since it is a service targeted at consumers it doesn't necessarily cover every solution under the sun.

A follow-up to this generic question, and a request I have heard more than once, is "I want my app to support both internal corporate users as well as external end-users. But I want the internal users to login with their corporate credentials, while the end-users use credentials of their choice. How do I do that?"

Well, that's simple. You just implement both AAD B2C and "regular AAD" in your app. Oh, is that not so straight-forward you say? I fully agree – keeping track of different identity stacks on the back-end can be a hassle, and you want to make sure the UI in front isn't too confusing either.

There are different ways to tackle this, so let's take a step back and look at the generic use case of supporting multiple IdPs regardless of AAD B2C or what have you.

Multiple identity providers equals…challenges…

If you create an internal app for Contoso where only internal users sign in the Azure AD wizards in Visual Studio will pretty much take you there. You have a login button, and when the user clicks it they get sent to the login page specific to your tenant. Type username and password, and they're in.

What if you want to create an app for end-users where they can sign in with Google or Facebook? Well, the easiest is probably having two login buttons - one saying "Sign-in with Google", and one saying "Sign-in with Facebook". The user is usually able to figure out which they want to use, and the rest happens automatically on their end. On your end you might have different code paths executing for the two identity providers, but so far so good.

Building on different buttons and branches you will eventually you hit a limit where you aren't interested in maintaining a bunch of integrations with different providers. This is usually the stage when you start looking into services like Azure AD B2C to act like an aggregator. So far we're only talking about social identities though. What if we are dealing with corporate identities?

The process is similar - let's say you build support for your own corporate ADFS for auth purposes. You then add your sister company's ADFS configuration to your code to let them login. Another company's ADFS and you find yourself in the same slightly cumbersome setup, so you decide that your app should only trust your ADFS, and let ADFS handle the rest of "the hassle". Your ADFS server is then configured with trusts to other companies while you only maintain the one connection from your app. Eventually this approach doesn't scale either, and you start looking into the Azure AD B2B feature to solve your federation woes.

Whew! Still with me? Ok, so we have a track for corporate identities, and we have one for social identities. And for some reason they can't all be covered by one "box in the middle" so we need to support multiple branches for the two worlds. There is of course always the choice of putting up any number of buttons for the user to choose among. "Login with your Facebook account" and "Login with your corporate account" on the same page. But what if the user has signed up for Facebook with their corporate email and can't really tell them apart? (And you want them to use the corporate account if they have one.) A neat solution is to have the user type in the username, and then redirect them to the correct identity provider based on what they type in so they can't use Facebook if they type their corporate email address.

Of course this is very dependent on how you build your UI with descriptions and terms, but you're starting to see the picture here. For some Microsoft services for instance you can type in andreas@contoso.com as the username, and then you're asked if you want to use the work or Microsoft account (if both exist).

So, that was a long interlude on the pains of supporting multiple IdPs, and that is why "just implement both B2C and regular AAD" is a bit more involved than three lines of code :) (I haven't actually shown code here, but if you try to work it out in Visual Studio you will see what I mean.)

Azure AD B2C Custom Policies

And that is why I think custom policies in Azure AD B2C is a sweet improvement. Now you can actually do this all on the back-end while still having just one "box in the middle" handling the federation for you. To be fair - it is only in a public preview for now, (AAD B2C is GA, but the custom policies feature is preview), so it is slightly unpolished for the time being.

Rather than rehash the official instructions for getting started I will point you to the steps outlined to make this work in the following links:
/en-us/azure/active-directory-b2c/active-directory-b2c-get-started-custom /en-us/azure/active-directory-b2c/active-directory-b2c-setup-aad-custom

Follow each step exactly as described, and you will get there. (At least setting up the auth components, an actual app is not covered by these instructions.)

Not seeing the "Identity Experience Framework"? I ran into that as well since I happened to run a really old B2C tenant from the Preview phase, and it wasn't linked to an Azure subscription correctly either. So, if that happens to you either link your B2C tenant, or create a new one first if necessary.

While JSON is easily readable by the average developer I will agree that it's not exactly a user-friendly process to get this configured for the time being. I can only assume this will be made easier eventually, but the value of the feature makes me willing to take the time needed nonetheless.

So, what will this look like in an app? Here's a sign-in pane with Google and Microsoft accounts (and a local option in case you don't want to be social):

Here's re-doing it with Facebook and Azure AD instead (why change just one parameter at a time):

Why the gibberish (Norwegian) language you say? This is based on your Windows regional settings, but I had some issues with my US laptop, so I had to go with a non-US setup for this screenshot :) It's not a B2C bug or anything like that. You should still be able to figure it out though. And notice how the corporate login button says "Contoso Employee"? It does not have to reflect the actual tenant name; if you want it to say something that is more recognizable by the users you set it to what you want it to say in the policy.

The number of lines of code I had to change: one.

Swapping public static string PolicySignUpSignIn = "B2C_1_B2C_Default_SignIn"; to have a value of B2C_1A_SignUpOrSignInWithAAD does the trick. (And that could easily have been externalized to a config file reducing the line number to zero.)

The actual code for this (or at least a snippet of it):

 
AuthenticationResult authResult = null;
try
{
   authResult = await App.PublicClientApp.AcquireTokenAsync(App.ApiScopes, GetUserByPolicy(App.PublicClientApp.Users, 
      App.PolicySignUpSignIn), UIBehavior.SelectAccount, string.Empty, null, App.Authority);                
}
...
var user = new AADB2CUser { 
   Name = authResult.User.Name, 
   Identifier = authResult.User.Identifier, 
   IdentityProvider = authResult.User.IdentityProvider 
};

This is from a very simple UWP app so that's about it when it comes to functionality though. You can check out the complete sample, or pull it down, by browsing to my GitHub profile:
https://github.com/ahelland/AADGuide-CodeSamples/tree/master/HelloAADB2C

Magic redirect to the correct Identity Provider

So, in a previous section I alluded to a possibly magic experience where corporate users are only seeing the AAD option. Where's that? Sorry, didn't go the extra mile, because I actually wanted both options onscreen at the same time :) What you could do is creating two separate custom policies - one with corporate IdPs and one with social IdPs. Having an initial textbox where you ask for the user name, and triggering the corresponding policy would be one way to solve it. The UX experts out there can surely figure out something snazzy-looking.

A bit of retrospection

AAD B2C should definitely be on the radar of identity devs in the future. The fun thing is that some of these features were actually available years ago in Azure as well in the Azure Access Control Service (ACS). Feature-wise it wasn't all that bad, but it had a couple of other limitations preventing it from going further. Sure, it didn't support OpenID Connect, (which is the basis of the custom policies used here), but it had other things going for it. It's good to see a new feature in Azure closing the gap on a veteran service :)

Comments

  • Anonymous
    June 02, 2017
    Andreas, thank you so much for this. This is exactly what I'm looking for!
  • Anonymous
    June 15, 2017
    Thanks Andreas. Very relevant.
  • Anonymous
    June 18, 2017
    Great one, Andreas!