Saturday, February 3, 2024

Azure AD B2C: Validating Output Claim from a Non-Self-Asserted Technical Profile

I had a requirement where I wanted to do an additional validation on a boolean claim value in an AAD B2C user journey. If the boolean claim value is true, I wanted to move forward in the user journey. If the value is false, I wanted to short circuit the user journey and return an error. 

I couldn't use Validation Technical Profiles, because the output claim I am validating upon was in a non-self-asserted technical profile (the claim was retrieved by calling an external REST endpoint)  and Validation Technical Profiles doesn't support non-self-asserted technical profiles.

In such cases, we can add an additional OrchestrationStep, do a Precondition in that particular step, assert and navigate the user to a self-asserted technical profile and display the error there.

So how do we do that? 

1. Define a ClaimType for a self-asserted technical profile.

    <ClaimType Id="errorMessage">
      <DisplayName>Please contact support.</DisplayName>

2. Define a ClaimsTransformation.

  <ClaimsTransformations> ...
    <ClaimsTransformation Id="CreateApplicationUserNotActiveErrorMessage" TransformationMethod="CreateStringClaim">
        <InputParameter Id="value" DataType="string" Value="Application user is not active." />
        <OutputClaim ClaimTypeReferenceId="errorMessage" TransformationClaimType="createdClaim" />

3. Define a self-asserted TechnicalProfile. Use the above ClaimsTransformation as a InputClaimsTransformation. Reference the ClaimType created in the first step.

    <TechnicalProfiles> ...
      <TechnicalProfile Id="SelfAsserted-ApplicationUserNotActiveError">
        <DisplayName>Error message</DisplayName>
        <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=, Culture=neutral, PublicKeyToken=null"/>
          <Item Key="ContentDefinitionReferenceId">api.selfasserted</Item>
          <Item Key="setting.showContinueButton">false</Item>
          <Item Key="setting.showCancelButton">true</Item>
          <InputClaimsTransformation ReferenceId="CreateApplicationUserNotActiveErrorMessage" />
          <InputClaim ClaimTypeReferenceId="errorMessage"/>
          <OutputClaim ClaimTypeReferenceId="errorMessage"/>

4. Introduce an additional OrchestrationStep with a Precondition before the last the OrchestrationStep. If the condition is not satisfied, use the created self-asserted TechnicalProfile.

  <UserJourney Id="...">
      <OrchestrationStep Order="9" Type="ClaimsExchange">
          <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
            <Value>isActive</Value> <!-- this claim is forwarded from a previous step -->
          <ClaimsExchange Id="SelfAssertedApplicationUserNotActiveError" TechnicalProfileReferenceId="SelfAsserted-ApplicationUserNotActiveError" />
      <OrchestrationStep Order="11" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />

And this is what happens when isActive claim is false. When it's true, the above OrchestrationStep will get skipped and the user journey will continue.
Self-Asserted Technical Profile
Hope this helps.

Happy Coding.


No comments:

Post a Comment