1
votes

How do you perform custom validation of users in an AAD B2C process?

I.e. We have a database of users with various attributes We want to use B2C for user authentication We need to ensure that the user signing up correctly matches an existing user in our database There is sensitive information that they'll get access to so this is really important During the signup journey, we want to have the user fill in their details but we need to be able to check some of those details against our database and fail the registration if they don't complete the details correctly. E.g. matching DoB, social security number, address, etc.

Is this the right way to achieve what we are thinking? https://docs.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-rest-api-validation-custom

What happens if validation fails ? Will the AAD account be deleted? What happens if validation is abandoned? There is a ‘first login’ flag in B2C, what happens if validation fails and user retries, how is this flag set and who controls it?

2

2 Answers

2
votes

Alternatively, you can create a validation technical profile, which encapsulates the attribute validation, that is executed by the account registration technical profile.

For example, you might have the following technical profile, which registers a local account with a social security number:

<TechnicalProfile Id="LocalAccount-Registration">
  <DisplayName>Local Account Registration</DisplayName>
  <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
  <Metadata>
    <Item Key="ContentDefinitionReferenceId">api.localaccount.registration</Item>
    <Item Key="IpAddressClaimReferenceId">IpAddress</Item>
    <Item Key="language.button_continue">Create</Item>
  </Metadata>
  <CryptographicKeys>
    <Key Id="issuer_secret" StorageReferenceId="TokenSigningKeyContainer" />
  </CryptographicKeys>
  <InputClaims>
    <InputClaim ClaimTypeReferenceId="email" />
  </InputClaims>
  <OutputClaims>
    <OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="Verified.Email" Required="true" />
    <OutputClaim ClaimTypeReferenceId="newPassword" Required="true" />
    <OutputClaim ClaimTypeReferenceId="reenterPassword" Required="true" />
    <OutputClaim ClaimTypeReferenceId="displayName" Required="true" />
    <OutputClaim ClaimTypeReferenceId="extension_SocialSecurityNumber" Required="true" />
    <OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="localAccountAuthentication" />
    <OutputClaim ClaimTypeReferenceId="executed-SelfAsserted-Input" DefaultValue="true" />
    <OutputClaim ClaimTypeReferenceId="newUser" />
    <OutputClaim ClaimTypeReferenceId="objectId" />
    <OutputClaim ClaimTypeReferenceId="sub" />
    <OutputClaim ClaimTypeReferenceId="userPrincipalName" />
  </OutputClaims>
  <ValidationTechnicalProfiles>
    <ValidationTechnicalProfile ReferenceId="AzureFunctions-CheckCustomer" />
    <ValidationTechnicalProfile ReferenceId="AzureActiveDirectoryStore-WriteUserByEmail-ThrowIfExists" />
  </ValidationTechnicalProfiles>
  <UseTechnicalProfileForSessionManagement ReferenceId="SSOSession-AzureActiveDirectory" />
</TechnicalProfile>

The first validation technical profile called "AzureFunctions-CheckCustomer", which is executed when the end user submits the registration form, invokes an Azure Function (or other external service) to validate the registration fields.

<TechnicalProfile Id="AzureFunctions-CheckCustomer">
  <DisplayName>Check Customer Azure Function</DisplayName>
  <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
  <Metadata>
    <Item Key="ServiceUrl">https://contoso.azurewebsites.net/api/CheckCustomer?code=...</Item>
    <Item Key="AuthenticationType">None</Item>
    <Item Key="SendClaimsIn">Body</Item>
  </Metadata>
  <InputClaims>
    <InputClaim ClaimTypeReferenceId="extension_SocialSecurityNumber" PartnerClaimType="socialSecurityNumber" />
  </InputClaims>
  <UseTechnicalProfileForSessionManagement ReferenceId="SSOSession-Noop" />
</TechnicalProfile>

If the Azure Function returns 200 OK, then the next validation technical profile called "AzureActiveDirectoryStore-WriteUserByEmail-ThrowIfExists" creates the local account and the end user can continue to the next step. If the Azure Function returns 409 Conflict with an error message, then the local account is not created and the error message is displayed to the end user.

1
votes

Is this the right way to achieve what we are thinking? https://docs.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-rest-api-validation-custom

Yes, that is correct.

What happens if validation fails ? Will the AAD account be deleted? What happens if validation is abandoned?

The account will not be deleted. One approach would be to add an additional attribute/claim and check that value in your app. Something like IsValidated. If !IsValidated send the user to Edit Profile from them to verify it.

During the Edit Profile user journey, if the user enters the values corrected, then the IsValidated gets set to true.