Creating an approval journey with Azure AD B2C

Image showing a green tick to approve
File:Approved-151676.svg — Wikimedia

This is a question that I have been asked a few times and there are no samples that I can refer people to.

The idea is that when someone signs up, they are not automatically added to B2C but rather have to wait until someone e.g. a manager approves the application

One approach would be the following three-step journey:

Step 1

Step 1 would be a user journey with a sign-up form and then an API that sends the approval manager an email. Included in the email is a magic link that contains all the user details. This link is clicked if the manager confirms the approval.

Step 2

Step 2 would be when the manager clicks the link. This kicks off a second user journey that reads the user details from the JWT in the magic link and then writes the user details to B2C. Then it sends the user an email with a magic link that contains the user’s email.

Step 3

Step 3 is when the user clicks the email, it kicks off a user journey that shows them a reset password screen so they can pick their password.

The user whose email is in the magic link is the one that has the password changed.

From a security view, this is vastly superior to the user entering their password in step 1. That would mean that the manager knows the password and the password is potentially exposed in an email.

Magic link

I posted about the magic link here using an id_token_hint.

The idea of a magic link is that there is a link in the email. The example below comes from the sample and “Confirm Account” is an example of the link.

Image showing a sample email with a hyperlink called “Confirm Account”

In our case, the email would be something like:

The following has requested access to B2C.

Name: Joe Bloggs

Email: joe@company.co.nz

Other details …

Reason for access: New employee in HR

and there would be a link saying “Approve access”.

The link would be a hyperlink to a URL like:

https://your tenant.b2clogin.com/your tenant.onmicrosoft.com/oauth2/v2.0/authorize?p=B2C_1A_MagicLink&client_id=xyz&redirect_uri=https://jwt.ms&nonce=abc&scope=openid&response_type=id_token&id_token_hint=eyJh…BKA

The JWT would look like:

{
"email": "joeb@company.co.nz",
"displayName": "Joe Bloggs",
"givenName": "Joe",
"surName": "Bloggs",
"extension_Reason": "New employee in HR",
"nbf": 1663813462,
"exp": 1664414662,
"iss": "your tenant.onmicrosoft.com",
"aud": "e00...a70"
}

i.e. these are the details supplied by the user during sign-up.

This is generated by the API. The API builds up the URL, constructs the JWT and signs it with a certificate as per the post above.

B2C checks the signature by getting the public key from the well-known endpoint as described here.

Email

You can send the email using SendGrid or Mailjet or your own SMTP server.

Step 1

This is just a standard sign-up policy that asks the user to enter the details and then builds up the email to the manager that includes the magic link.

Step 2

When the manager clicks on the link (i.e. approves the user creation), it invokes a custom policy.

As usual, this policy is in a gist. The policy:

  • Uses “IdTokenHint_Asymmetric_ExtractClaims” to get the user details
  • Writes the user details to B2C using “AAD-UserWriteUsingLogonEmail”
  • Calls an API to kick off a reset password flow

Note that multiple claims can be passed in the magic link.

The policy creates the user in B2C

Image showing a B2C user — joeb@company.co.nz

The reason the display name is “unknown” is because that is the default behaviour of “AAD-UserWriteUsingLogonEmail”.

Step 3

The last part of step 2 calls another API that sends an email with a magic link. This link has a JWT that just contains an email address.

It invokes a custom policy that:

  • Uses “IdTokenHint_Asymmetric_ExtractClaims” to get the email address
  • Calls “AAD-UserReadUsingEmailAddress” to get the user’s objectID
  • Calls “LocalAccountWritePasswordUsingObjectId” to invoke the password reset flow

The fact that the email address is in the JWT is why the JWT is signed. If a third party intercepted the email and tried to add a different email address to the JWT, B2C will reject it because the signature is wrong.

You can also refer to the invitation/magic link samples e.g. this.

All good!

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Rory Braybrook

Rory Braybrook

514 Followers

NZ Microsoft Identity dude and MVP. Azure AD/B2C/ADFS/Auth0/identityserver. StackOverflow: https://bit.ly/2XU4yvJ Presentations: http://bit.ly/334ZPt5