Implementing security questions and answers on Azure AD B2C

Rory Braybrook
The new control plane
3 min readApr 27, 2021
Secret account by Wolf Böse from the Noun Project

This was a request from a customer and on googling it, I found there was nothing!

This could be because secret Q&A are not very secure and have pretty much been deprecated as a security feature.

But sometimes it’s all you have as an option.

NZ is an agricultural country and agriculture and tourism are its biggest income earners. (Well, tourism not so much at the moment 😢)

So we get lots of seasonal and itinerant workers who go from farm to farm picking fruit, pruning the grape vines or whatever.

Some of them have no email address and don’t have a NZ SIM card.

When they arrive at a farm, they get a username and a password. That’s OK to login to whatever apps they need to use.

So what do you do for self-service password reset? They can’t verify who they are by email or phone. They would have to go back to the office to get their password reset by someone but the office could be km’s away and maybe there’s nobody there. Also, they tend to be paid by the amount of work they do (e.g. weight of apples picked) and if you are trudging all over the farm looking for someone to help, you don’t get paid.

Hence, security questions and answers.

When they onboard, they get (say) three questions that they have to answer.

The questions and answers can be stored in B2C as extension attributes.

The on-boarding part is just a standard self-asserted signup page so I won’t go into that.

We want the password reset process to ask one of the three questions at random and if they answer correctly, they get the standard password reset page.

I based the solution on the username SUSI custom policy in the samples.

Note that for built-in policies, the username setting is tenant wide. In custom policies, you can mix and match between emails and username. You can use both in the same policy.

As usual, the policies are in a gist.

The SUSI policy is not used in the password reset flow but I’ve added it as you have to create a valid username first.

The policy in the sample asks you for an email address for password reset (which would defeat the purpose) so note that I added the metadata:

<Item Key="EnforceEmailVerification">false</Item>

in order to remove this.

The policy manually checks if the random number is 0,1 or 2 so this solution wouldn’t really scale if you had (say) 20 possible options.

The security questions and answers are hard-coded in this example.

The questions and answers are:

  • First name = Tom
  • Surname = Jones
  • Nickname = Tommy

To pick which question to ask, we need a random number.

<ClaimsTransformation Id="SetRandomNumber" TransformationMethod="CreateRandomString">
<InputParameters>
<InputParameter Id="randomGeneratorType" DataType="string" Value="INTEGER"/>
<InputParameter Id="maximumNumber" DataType="int" Value="3"/>
<InputParameter Id="stringFormat" DataType="string" Value="{0}"/>
<InputParameter Id="base64" DataType="boolean" Value="false"/>
</InputParameters>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="randomNumber" TransformationClaimType="outputClaim"/>
</OutputClaims>
</ClaimsTransformation>

This produces one of three values viz. 0 to 2.

The user first has to provide their username.

This is checked to ensure that it is valid (and in the actual implementation, would have to read the user’s Q & A extension attributes).

They then get one of the questions:

If they answer correctly, they get to the “Change Password” screen.

All good!

--

--

Rory Braybrook
The new control plane

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