Today let’s go ahead and discuss the actual implementation of our way to validate Sitecore users as customers via Azure B2C. You may want to check part 1 to get a sense of what we will cover here.
Before you all hate me, as I was writing this post it became evident that we will need to cover the actual code in a third part of this series – setting up the B2C directory and explaining some things about how will our app work has taken more writing than I originally anticipated. So, bear with me, ok?
Let’s start with some considerations and move forward from there, shall we?
As I mentioned in my last post, we decided to build our custom implementation for processing the OpenID stuff that happens between our application and the B2C directory holding the customers for AwesomeCompany, our fictional customer. It’s mandatory to mention that the procedures shown here are simplified and by no means constitute production ready code or best practices – but they will give you a pretty close idea.
The B2C setup
As a first step, we need to set up a B2C repository. As you know, it works on top of AzureAD, so it makes sense that setting that up is very similar to setting a regular AD instance.
You can go to the B2C documentation site to know more, but here I’ll show the basic steps. Again, I’ll simplify most of it in the spirit of keeping this post short.
- Login to your azure management portal (manage.windowsazure.com)
- Go to your Active Directory list and add a new one.
- You need to check the “this is a B2C directory” – This option is only available on creation, so if you cannot convert a regular AD to a B2C directory!
- Wait a couple of minutes and you’ll have it ready.
- Now, click on the newly created directory and select “manage B2C settings” – the B2C management page will open.
You can see several sections there. The ones we will use for this post are:
- Applications – We will need to register our application so B2C can process the requests correctly.
- User Attributes – Here we will define the claims that will be available, that is, info about our customer.
- Policies – B2C incorporates the concept of policies, a cool way to simplify account management. In the spirit of keeping this simple, we will use the “Sign up or sign in policies” section to define a couple.
Before we go ahead and configure those, let’s take a look at the flow that we will use for our application.
Explanation: Apart from witnessing my amazing drawing skills, you can see that the application makes a request to sign up or sign in the customer to Azure B2C. Azure then will take the responsibility to perform the requested action, as long as the request is made correctly and the application is registered in B2C. When successful, it will return an authorization token in a post request to a url that is preconfigured. The application then will request the encryption keys that are needed to validate the token, and B2C will comply happily. Finally, the application will validate the token and sign in the customer. It is, indeed, a very, very simple flow.
So, with that out of the way, let’s continue.
Getting on with it
I said before that we are doing our own implementation just to avoid adding the complexities of adding Owin to our Sitecore solution. Therefore, we will make the requests ourselves. This B2C page contains useful info about those requests.
This is the format that our authorization GET request will use:
https://login.microsoftonline.com/(OUR B2C TENANT)/oauth2/v2.0/authorize?
client_id=(OUR APPLICATION ID)
&redirect_uri=(OUR URL IN CHARGE OF PROCESSING THE RESPONSE)
So basically, we need 6 values to form the URL for our request:
- (OUR B2C TENANT) – self explanatory. In our example, “SCB2C.onmicrosoft.com“.
- (OUR APPLICATION ID) – We’ll get it shortly.
- (OUR URL IN CHARGE OF PROCESSING THE RESPONSE) – The url to which B2C will post an authorization token.
- (STATE DATA) and (NONCE DATA) – arbitrary data that will return as-is in the B2C response.
- (OUR POLICY) – The policy we are using. We’ll get it shortly too.
For this example, we’ll use (STATE DATA) to send the url the user was visiting before requesting the sign in/up, and we’ll use (NONCE DATA) to add an additional verification, for avoiding a token-replay attack.
Back to settings
To get all the values we need, we need to register an application into B2C, and then set up the policies we’ll use.
To register an application, just go to Applications and create a new one in your B2C management page. Our application has the very creative name of MySitecoreApplication, and since we are developing it, it has the default binding in our DEV machine (https://localhost, and YES it MUST be https or it won’t work).
Additionally, we also have a very creative name of ProcessB2CResult for detecting when we need to handle the results in our app. Finally, we need to click the Generate key button to generate a key that will be used to encrypt tokens for this application. No need to copy it, btw. Also, since this is a webb application we need to enable the Web App-Web Api switch, but not the Native Client switch, and we will also enable implicit flow.
After the App registration, if we go and open it again we will see an Application Client ID field containing our client ID. That’s the one we need to copy!
Seems too much when written, but it’s easy, so don’t complain.
Now, let’s create the policy. As I mentioned before, for this example we are using a sign up/sign in policy just to avoid managing more than one. Similar to the creation of an application, creating a policy is straightforward.
Just remember to set a name (MyPolicy, which will be ultimately changed to B2C_1_MyPolicy), choose the ID provider (we’ll use “email address“, which comes predefined), the attributes that will be asked from the user when signing up, and the claims that will be included in a successful token response.
We now have a policy. Yay! Almost there.
Before we end this post in another cliffhanger (again, sorry for that ), we need to deal with another piece of info we will need. If you see the rudimentary flow graphic above, you will wonder where the heck do we get the url to get the crypto keys to validate the token.
Well, if you check in your B2C settings page your newly created policy, you’ll discover a link in there. That’s the metadata endpoint link. If you just make a plain GET request to that endpoint, you’ll get info about your policy.
The Json that comes back from that endpoint contains a property, jwks_uri, that will contain the url of the endpoint that will provide the keys. You’ll also find other endpoints, most notably the aforementioned authorization endpoint and the signout endpoint.
It may make sense to call this metadata endpoint at the start of the application and save the results once, rather than calling it everytime we need to make a request.
Wow, that was long, but necessary. In the third, and (I promise) last part of this series, we’ll finally build some code to make the necessary requests, validate the token, and sign the customer into our site. Additionally, we will deal with possible B2C errors and “unhappy path” situations.
Have a great day, everyone, see you soon!