A Dark Tower inspired guide to getting started with Azure AD B2C

A bit of backstory

I’m a BIG fan of The Dark Tower books (talk to me if you have questions re movie). As a client/mobile app developer, I feel like Roland (the Gunslinger) wandering in a tech world “that has moved on” from client apps to JavaScript.

Stephen King - The Waste Lands Book 3

 

And from what I hear re JavaScript, the chaotic ruins of mid-world is a good analogy =)

In my traditional `saraford` fashion, I’m going to blog what I’m learning on the Azure AD B2C team, just in case it can help someone else. Oh yeah, I’m back at Microsoft!

But more importantly, blogging about what I’m learning ensures that I know the material, forcing me to ask all those embarrassing newbie questions like, “what’s a tenant?”

For the past month, I’ve been heads down learning about Azure AD B2C, what it is and what it is used for. And as client app dev, there’s A LOT of ramping up I have in front of me. A LOT.

Just like my first punch thrown in karate 20 years ago, you just have to start somewhere…

What’s included in this blog post

  1. What’s Azure AD B2C
  2. About the Getting Started Sample
  3. What does this sample do?
  4. Where Azure AD B2C comes in
  5. Creating an Azure AD B2C Tenant
  6. Registering the Web App
  7. Registering the Web API
  8. Defining the permissions / scopes for an API
  9. Giving the Web Application permissions to the API
  10. Creating a “Sign In or Sign Up” policy
  11. To the code!
  12. Run your app
  13. Putting it all together
  14. Go then… there are other policies than these

1.  What’s Azure AD B2C?

You use B2C when you want users to sign up for your apps using their own social identities (e.g. twitter, facebook, etc.) or email addresses (“local account”).

Your users can manage editing their profiles, resetting their passwords, etc. while you can focus on developing your apps instead of learning how to be an Active Directory administrator.

And yes, in the spirit of completeness, there’s a third type where your users can sign-in using a username (another local account type), but let’s skip that for now.

2.  About The Getting Started Sample

This sample is where I had my lightbulb “I get it now” moment, only thanks to a very patient onboarding buddy who didn’t mind explaining Reply URIs and Fiddler several times.

Now I want to share with you all my same lightbulb moment – just to get you up and running with the sample.

If you’re following along at home, go to the .NET Web App and Web API sample and clone.

Note: if you are using GitHub Desktop on Windows with clone location defaults, you’ll need to rename the cloned folders; otherwise, the file paths will be too long.

BTW I’m not discussing the libraries being used (MSAL and OWIN) here. Honestly, I haven’t ramped up on that yet, so stay tuned.

3.  What does this sample do?

This sample is a TODO application. Inside the solution, you’ll find two projects:

  • TaskWebApp – A web application where you can enter your TODOs. (Note: these calls go directly to the web API)
  • TaskService – A web API that manages your TODOS, e.g. all the CRUD operations. The web app simply calls this API and displays what the API returns.

This sample demonstrates using the Sign Up or Sign In policy to create / sign in with an email address. We’ll cover the social identity provider later.

Have I mentioned I’m not a web dev, wandering in a world that has moved on into JavaScript? But I’m changing that starting now!

Here’s how the sample works once we’ve wired it all up.

  1. The user signs up to use the application by clicking the Sign up / sign in link.

ASP.NET Web App as a To-Do List running

2. The user enters his/her information.

Note: I’m demo’ing a “local account” that is, signing up via an email address.

Note: You need to use a valid email address to receive the verification code. That’s just how this sample is configured.

signing up as Roland Deschain

3. The user sees his/her display name (and if you wire-up the entire sample, you’ll get edit profile and reset password working – but for now let’s just get To-Do list working)

Roland Deschain as signed in user

4. Once logged in, the user can click To-do List and enter some Todos.

The To-Do List - Tell Oy! he's a good Oy!

Note: all these CRUD operations are HTTP Requests to the Web API.

4.  Where Azure AD B2C comes in

If you’re like me, you might be wondering, well, why not just have the Web App handle all the CRUD operations? This is an example of how the “world has moved on” while I was PM’ing the last several years. Let’s assume you not only have a Web App, but you also have mobile apps on different devices. All these apps need to talk to the same service, i.e. some Web API, to handle the CRUD operations.

If you’re looking at B2C, it is because you have a service out there and you want your application (client, mobile, web) to consume that service.

Here’s what the diagram looks like. Note this is a “classic Open ID connect flow” which I’m still ramping up on.

High level diagram of who is calling whom

Let’s break this diagram down a bit:

  1. Clicking Sign up / sign in: the user is sent to a login.microsoftonline.com/… page to sign up or sign in.
  2. B2C sends back two items(1) if the login (or sign up) is successful:
    • id_token – this token(2) has info (called claims) about the user, e.g. Display name. The id_token is handed out when the user is who they say they are, i.e. AutheNtication. Note the capped `N` for emphasis.
    • Access token – this token tells the application what permissions, called scopes(3), this user has for whatever registered services.
  3. Web App to Web API: When the Web App calls the Web API, it sends the Web API an access token. The Web API looks at this token and says, “yep, this user has the right permissions (or scopes) to call this API.” Otherwise, if you try to click on the To-do List link without setting up these “scopes”, you’ll get an Unauthorized error message on the website (even though you’re successfully signed in.)
  4. Trust relationship – this really should be item 0. The Web API needs a way to “trust” this access token. Otherwise, it’s just a random string of numbers and letters. This trust relationship with B2C is defined via the portal, which you’ll see further on in this walkthrough. In addition, the web app needs a way to be registered with B2C, which is done via the portal as well(4).

(1)To be more accurate, this is the grant type = authentication code flow, where the browser receives an authorization code, which gets traded for an access token that’s only sent to the browser… but for now for us non-web devs, let’s stay high level.

(2)A token is just a string of numbers and letters. More on tokens later, but for now, just know it is a string that is sent back. And when this string is decoded, you can see things (e.g. Display name, permissions/scopes) inside (called claims). When a token decoded, you can see what permissions (or scopes) are defined (or claimed) within this token. We’ll look at a token in depth in a future blog post. For now, let’s just get this running.

(3)“Scopes” are the official term used inside a token to represent permissions. If you’re looking at a decoded token and see “scopes”, think permissions. And if you’re reading about permissions, think “scopes”. But “scopes” is the official term used in the token.

(4)Anytime “something” needs to talk to B2C, that something has to be registered with B2C, hence why you’ll hear a lot about registering your app or service to B2C. All this registering is done via the Azure portal

Before we jump into registering our applications, let’s find out a bit more about these two projects included in our sample so we know what we’re registering with B2C.

5.  Creating an Azure AD B2C Tenant

Now that we know what our samples will do, we’ll need to first create a B2C Tenant (also known as a Directory). This tenant/directory thingy is the triangle you saw in the above diagram.

If you’ve already have a test B2C Tenant, jump down to the next section. Otherwise, following along!

Follow the directions under the headings

  1. Create an Azure AD B2C tenant and
  2. Easy access to settings

With the caveats:

  1. Don’t worry about Linking to your subscription right now. Everything you need to do to get these samples up and running can be handled without a subscription.
  2. Make sure you follow the Easy access to settings steps, specifically for the “To switch to your Azure AD B2C tenant, select the B2C directory in the top-right corner of the portal.” I missed this the first time, and I was totally confused why I didn’t have admin rights. The reason was that I was signed in using my microsoft.com email address, so I didn’t have admin rights to the overall Microsoft company directory =P
  3. For the Organization name and Initial domain name, instead of `Contoso`, use <Your Fictitious Test Company Name>. The Initial domain name must be unique across the board since it is the unique identifier for a directory.

 

Contoso Tenant name already in use by another directory

Now your B2C tenant should be all ready to go, but let’s first talk about these applications (the Web App and Web App) we’re about to register.

6.  Registering the Web App

What the Web App does

This is our web app. Notice it is running on https://localhost:44316

  • The To-Do List link calls the Web API (the other project in the solution)
  • There’s a Sign-up or Sign-in link to the far right. The user needs to be signed in to access data from the Web API. (In theory, each user is accessing his/her own todo list.)

The To-Do List link calls the Web API

What to tell B2C about the Web App

To tell B2C about your Web App, you’ll need to register your Web App with B2C via the Azure portal. Make sure you’re in your B2C tenant in the upper right drop-down.

List of your directories

There are step by step directions for registering an application but here’s the resulting screenshot for this particular Web App sample. I bold Web App as to not confuse with Web API project.

line by line description of the app registration page

To recap the screenshot above:

  • Name – for you as a human to identify your app in the Azure portal
  • Application ID – what you’ll copy into the sample application
  • Web App / Web API – yes, we’re registering a Web App
  • Reply URL – use https://locahost:44316 since this is what the Web App sample is using when you run it locally. This is needed for B2C to know where to send the access token to. (I’m not a web developer yet, so just go with this that this magically works.)
  • App ID URI – leave this blank. We’ll use this when we register our Web API.

Getting the Client Secret

When you first want to talk to B2C from your Web App, you need to send it the Client ID (aka the Application ID as shown in the portal) and the Client Secret. It’s kinda like “I am who I say I am, and here’s the Client secret to prove it.” These client credentials are sent via the HTTP request in the Web App during the initial `/authorize` endpoint call, kicking off the rest of the authorization flow. You’ll see where to add these in the code later in this walkthrough.

To get your Web App client secret, go to the Keys page for your Web App registration.

General - Keys link

Note: when you click Generate key, you’ll only get to see it this one time. Make sure you copy it down somewhere if you’re not ready yet to paste into Visual Studio.

7.  Registering the Web API

Now that the Web App is registered (although we’re not completely done yet – more later), let’s go register the Web API.

Here’s what the resulting screenshot should look like:

line by line description of registering an API w B2C

To recap the above screenshot:

  • Name – for you to identify your Web API in the Azure portal
  • Application ID – to put into your code
  • Web App / Web API – yep, we’re a Web API
  • Reply URL – this is the localhost:port the sample uses.
  • App ID URL – This is needed for the Web API to tell B2C, “Hey I want an access token (with these scopes*) for this particular API because a tenant could have more than 1 registered API. But scopes are only defined for a particular API. In other words, scopes are not global to a tenant.

*This got me thinking: could you have an access token without scopes? I guess so (and I’m sure I created one or two accidentally when I first got started), but then it would be like saying, “here’s a driver’s license card, but just the physical blank card your driver’s license would have been printed on.” Sure, you’d have a card, but it wouldn’t get you far.

This Web API registration also defines the trust relationship. Since the API is now registered with B2C, it can now “trust” access tokens sent to it from B2C.

8.  Defining the permissions / scopes for an API

Now we’ve printed out a “blank driver’s license.” Now to add some content or permissions (or scopes) to be contained within our access token.

Still within the Web API registration, click on Published scopes (Preview)

General - API Access - Published scopes

And fill out your scopes as shown below.

How scopes are defined

Why the “Hello”? No idea. This was just the example I learned. But the main takeaway is the Scope field is the name of the scope / permission that will appear in the token and also that you’ll use in your code.

9.  Giving the Web Application permissions to the API

Alrighty. What we’ve done above is say, “Hey (mid-)world! This API will have the following permissions: Read, Write.” I guess you could have also added a permission called, “WriteOnly” or “SaraNoH” that only allows read access to Sara’s who don’t have an ‘h’ in her name. The point is that you get to define the permissions / scopes for your API.

Next, we’ll tell B2C which scopes the Web App has permissions to use.

Switch over to your Web App in the Portal and click API access (Preview)

General - API access - API access Link

Now click Add at the top. A window appears on the far right hand side.

You’ll want to select your Web API by it’s human-identifiable portal name and select the scopes you just created in the Web API registration.

Selecting the desired scopes to be used by the web app

And make sure you click ok at the bottom!

Ok button

Now your Web App and Web API should be registered properly with B2C.

Lastly, before we can leave the Azure Portal, we need to create a “policy” – i.e. how you want your users to sign up for your apps.

10.  Creating a “Sign In or Sign Up” policy

Follow the steps listed under the header: Create a Sign in or Sign up policy.

A few things I missed the first time:

  • Sign up attributes – these are the fields your users will see when they sign up for your app
  • Application claims – these are the “claims” that will appear in your token. For now, just make sure that you check User is new and User’s Object ID. I missed those the first time.
  • Call the policy b2c_1_SiUpIn. This is the name I use the same in the code samples below (just in case the policy name in GitHub gets changed at any point). Also I’m not 100% certain if policy names are case sensitive, but I’ll find out.
  • For the Select reply url, note that you’ll need to select the application first.

selecting application to define the reply url

Optional: You can click Run Now if you want to verify you can sign up for your app. But it won’t do much. You’ll need to go to the main tenant page and check under Users and Groups to verify (I believe – I’m still learning).

11.  To the code!

Now that the Web App and Web API are registered with B2C and you have a policy, it’s time to wire-up the samples to talk to your B2C tenant.

Open the B2C-WebAPI-DotNet solution in Visual Studio.

Note: By default, the samples are wired-up to talk to a demo tenant called `fabrikamb2c.onmicrosoft.com` To have these samples talk to your specific tenant, you’ll want to update the Web.config for both projects.

BTW: you can go to Tools – Options – Projects and Solutions – General page and check the Track Active Item in Solution Explorer to keep track of which Web.config you are editing.

In the TaskWebApp project, open the Web.config file:

1. Make the following updates:

<add key="ida:Tenant" value="<Your Fictitious Test Company Name>.onmicrosoft.com" />

<add key="ida:ClientId" value="<The Application ID for your Web App as seen in portal" />

<add key="ida:ClientSecret" value="the Web App secret - if you didn't copy it, delete and regenerate" />

 

2.  Update the value with the value you used to create your policy. If you’re following along this example, use the value below

<add key="ida:SignUpSignInPolicyId" value="b2c_1_SiUpIn" />

3.  Comment out the aadb2cplayground site and uncomment the `locahost:44332` for the TaskServiceUrl – this will be the localhost port for the Web API to run on. Your code should look like the following below.

 

<!--<add key="api:TaskServiceUrl" value="https://aadb2cplayground.azurewebsites.net/" />-->

<add key="api:TaskServiceUrl" value="https://localhost:44332/"/>

4.  Give the App ID URI of the API to the Web App so it can tell B2C which API it wants permissions to by commenting out the fabrikamb2c tenant and updating your scopes as follows:

<!--<add key="api:ApiIdentifier" value="https://fabrikamb2c.onmicrosoft.com/api/" />—>

<add key="api:ApiIdentifier" value="https://dorfarasB2CTenant.onmicrosoft.com/api/" />

<add key="api:ReadScope" value="HelloRead" />

<add key="api:WriteScope" value="HelloWrite" />

Next, in the TaskService project, open the Web.config

1. Make the following changes:

<add key="ida:Tenant" value="<Your Fictitious Test Company Name>.onmicrosoft.com" />

<add key="ida:ClientId" value="<The Application ID for your Web API as seen in portal>"/>

2.  Update the value with the value you used to create your policy. If you’re following along this example, use the value below

<add key="ida:SignUpSignInPolicyId" value="b2c_1_SiUpIn" />

3.  Update your scopes as follows:

<add key="api:ReadScope" value="HelloRead" />

<add key="api:WriteScope" value="HelloWrite" />

And that’s it! Well almost…

12.  Run your app

You’ll need to run both the Web App and the Web API at the same time. You can do this by configuring the Solution – Startup Project to run both at the same time, e.g.

Change None to Action for both projects under Multiple Startup Projects

I love finding out new stuff about Visual Studio! I don’t know how I didn’t know about this back in the day, or maybe it wasn’t available back then. /shrugs

You should now be able to perform the scenarios discussed at the start of this blog post that you began reading 20 years ago =) What can I say? I just like to write!

  1. Go to the Web App (that’s the website on http://localhost:44316) and click the Sign In / Sign Up button to sign up.
  2. Once signed in, click on the To-Do list link.

If all goes well, you’ll be able to edit your own todo list. If things don’t go well, (cry your pardon sai), leave a comment below. I’m putting together a FAQ of what the different sort of error messages look like when putting together this sample.

Old SDET habits never die.

13.  Putting it all together

Something that would have helped me out big time at the beginning would have been the following diagram to see how the Azure portal App registration fields come into play.

Final diagram showing reply URL, App ID URI, etc.

 

14.  Go then… there are other policies than these

We only looked at the Sign Up or Sign In policy. There are other policies for other things, like resetting passwords, editing a profile, etc. which we’ll get to at another time.

https://docs.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-reference-policies

And yes, I really love The Dark Tower, movie, book, comics. Seriously if you have any questions about the movie, I’m here for ya!

One thought on “A Dark Tower inspired guide to getting started with Azure AD B2C

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s