Authenticating with username and PIN in Azure AD B2C

Rory Braybrook
The new control plane
2 min readMar 16, 2021

Normally, you would login with an email address but you can also login with a username which is essentially any string of characters e.g. “123456”.

In built in policies, you can configure this on the identity provider but note that this is tenant wide.

You can do it per application with custom policies.

Changing to username is defined by the metadata:

<Item Key="LocalAccountType">Username</Item>                             <Item Key="LocalAccountProfile">true</Item>

and:

<Item Key="setting.operatingMode">Username</Item>

The next part of the requirement was to login with a numeric PIN rather than a password e.g. any group of numbers with minimum of 4 digits and maximum of 6 digits.

Configuring complexity requirements for passwords using custom policies is described here.

The changes to the above policy as described below.

The predicates are:

<ClaimType Id="newPassword">
<PredicateValidationReference Id="CustomPassword"/>
</ClaimType>
<ClaimType Id="reenterPassword">
<PredicateValidationReference Id="CustomPassword"/>
</ClaimType>
<Predicates>
<Predicate Id="LengthRange" Method="IsLengthRange">
<UserHelpText>The password must be between 4 and 6 numeric characters.</UserHelpText>
<Parameters>
<Parameter Id="Minimum">4</Parameter>
<Parameter Id="Maximum">6</Parameter>
</Parameters>
</Predicate>
<Predicate Id="Number" Method="IncludesCharacters">
<UserHelpText></UserHelpText>
<Parameters>
<Parameter Id="CharacterSet">0-9</Parameter>
</Parameters>
</Predicate>
</Predicates>
<PredicateValidations>
<PredicateValidation Id="CustomPassword">
<PredicateGroups>
<PredicateGroup Id="LengthGroup">
<PredicateReferences MatchAtLeast="1">
<PredicateReference Id="LengthRange"/>
</PredicateReferences>
</PredicateGroup>
<PredicateGroup Id="CharacterClasses">
<UserHelpText>The password must be 4 numeric characters:</UserHelpText>
<PredicateReferences MatchAtLeast="1">
<PredicateReference Id="Number"/>
</PredicateReferences>
</PredicateGroup>
</PredicateGroups>
</PredicateValidation>
</PredicateValidations>

We need to remove the requirement for strong passwords.

The “SignUpOrSignInWithUsername” user journey calls “LocalAccountSignUpWithLogonName”. That calls “AAD-UserWriteUsingLogonName” that requires the following change.

<PersistedClaim ClaimTypeReferenceId="passwordPolicies" DefaultValue="DisablePasswordExpiration, DisableStrongPassword"/>

The sample does not ask for display name when you sign up.

This results in:

To get around this, add “displayName”.

In “AAD-UserWriteUsingLogonName”:

<!-- Optional claims. -->
<PersistedClaim ClaimTypeReferenceId="displayName"/>
<PersistedClaim ClaimTypeReferenceId="givenName"/>
<PersistedClaim ClaimTypeReferenceId="surname"/>

In “LocalAccountSignUpWithLogonName”:

<OutputClaim ClaimTypeReferenceId="displayName" Required="true"/>
<OutputClaim ClaimTypeReferenceId="givenName" Required="true"/>
<OutputClaim ClaimTypeReferenceId="surname" Required="true"/>

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