Authenticating a Sitecore external user via Azure AD B2C gotcha list
The Requirements
The requirement is to manage user signups in one place by using Azure AD B2C policies. Currently, for different types of users, there are login processes managed at different locations. By using Azure AD B2C, I could manage the user login in once place with minimum coding, inviting Users to signup by email using a one time code.The user is then able reset their password, allowing auto login too.
The Gotchas
For your sign up and sign in there are three policies available:
- Sign-up policy
- Sign-in policy
- Sign-up or sign-in policy
Because signup is through invited email with one time use code, I chose to use sign-up policy in my POC and use sign-in policy for user sign in. The sample code it worked in no time.
But there were some gotchas:
1. The UI customization is not available for sign-in policy.
According to the docs.microsoft I could customize my signup policy.
However, I found out that this is not available for sign-in policy, although is it available for the other policies.There is not a setting for sign-up policy to allow Azure AD B2C to retrieve your customized UI page.
2. No control of password reset.
On sign-in page there is a link that says "Can't access your account?" which allows the user to reset the password.
However, this is not using the password reset policy. Therefore I have no control over it.
When the user successfully resets their password, I need to auto log in the user, which does not seem possible.
In addition, this is the Microsoft default password reset process that is not available for UI customization pages.
You can change the logo or background but it will not use your UI customization pages like other policies.
Therefore I have to use the sign-up or sign-in policy which allows me to:
- Full customization of the log in screen
- Full control of password reset
Because the "can't access your account" is built in element, it will be included on the page. However, I could use CSS to hide this link and set an empty customized page which will redirect to our customized password reset page. In case anyone using the view page element finds this link and tries to access it, it will simply redirect to our password reset page where I have full control.
3. No localization
I thought as I have full access to the UI customization pages, I will be able to provide localized content. However, it turned out that it was not supported according to Azure Active Directory B2C FAQs: https://docs.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-faqs
That was a bummer I have tried JQuery and JavaScript, but once Azure load my static page, all the client side scripts got removed. The work around we found is to use CSS with radio buttons. This allows the users on the client side to use radio buttons to show different languages of the page. However the elements from Azure will remain in English.
4. No user names available in sign-up policy claim
At the user signup, I was expecting the username would be included in the claim but it wasn t. I found the workaround at stackoverlow with OWIN.
However, due to the solution dependencies, using OWIN was not an option. Microsoft had great example code at:
I was be able to use the get username by OID to retrieve the user name. One gotcha I had here is the client secret where in multiple blogs articles I see the App key used as the client secret.
However the client secret for Graph API is not the App Key. The details of creating the client secret can be found at:
5. Error handling
There are error code such as "AADB2C90118" for password reset that I found on the web, but in my testing, I found more error codes which had not been documented.
Here are some of the error codes I faced__:__
- AADB2C90091 - the user has cancelled multi-factor authentication.
- AADB2C99002 - this user does not exist and profile AAD-UserReadUsingObjectId requires the user to have already been created
- ADB2C90157 - User as exceeded the maximum number for retries for a self-asserted step.
6. Log out user
When the user clicks on log out, I want to ensure the user is logged out from both Sitecore and Azure AD B2C. The reason for this is because I want to ensure the user needs to enter their credentials every time. One gotcha I had is that at the Sitecore session time out, caused by no action on the browser or closing the browser, the user will be logged out from Sitecore but not from Azure AD B2C. To handle this you can add your logic at the sessionEnd event or you can tap into the sessionEnd pipeline to ensure log the user out form Azure as well.