Azure AD B2C: User Journey Time Out through Custom Policy
Published Oct 25 2022 01:28 PM 2,319 Views
Microsoft

In the scenario I refer to this blog, Customer would like to have the session timeout at a particular step during Sign-up flow rather than having it at the end of the flow. This Customer uses Azure AD B2C as the identity platform for their application and implements the user journeys through custom policies. In the doc mentioned Configure session behavior - Azure Active Directory B2C | Microsoft Learn, session timeout could be configured through custom policy, but the issue is Azure AD B2C session does not start until the user completes sign up or sign in process. Until then, there are no session in B2C, hence the custom policy mentioned in the docs did not meet the need of the customer.  I will discuss the solution about how to implement a timeout during user journeys before the B2C session starts.

 

Solution:

 

This sample shows how to measure the time takes the user complete the sign-up or sign-in flow. The sample starts checking the time before the first orchestration step, before the user signs-in or sign-up. You can call the GetEndDateTime claim transformation before the step you would like to have time out and add a self-asserted technical profile when the validTimespan claim is False.

 

The time window is configured in seconds in the CompareStartAndEndTimes claims transformation. 

 

Step 1: Add the Claim Transformations to get the Start Time, End Time and CompareStartAndEndTimes

 

 

 

 

<ClaimsTransformations>
      <!-- Demo: Set the 'startDateTime'  claim with the current date and time.
                 This claims transformation at the beginning user journey-->
      <ClaimsTransformation Id="GetStartDateTime" TransformationMethod="GetCurrentDateTime">
        <OutputClaims>
          <OutputClaim ClaimTypeReferenceId="startDateTime" TransformationClaimType="currentDateTime" />
        </OutputClaims>
      </ClaimsTransformation>

      <!-- Demo: Set the 'endDateTime'  claim with the current date and time.
                  This claims transformation runs before the last step of the user journey-->
      <ClaimsTransformation Id="GetEndDateTime" TransformationMethod="GetCurrentDateTime">
        <OutputClaims>
          <OutputClaim ClaimTypeReferenceId="endDateTime" TransformationClaimType="currentDateTime" />
        </OutputClaims>
      </ClaimsTransformation>

      <!-- Demo: Determine if startDateTime plus the timeSpanInSeconds parameter is later then the startDateTime. 
                 If it's later, the user completed the sign-up or sign-in flow within the time (60 seconds). 
      -->
      <ClaimsTransformation Id="CompareStartAndEndTimes" TransformationMethod="DateTimeComparison">
        <InputClaims>
          <InputClaim ClaimTypeReferenceId="startDateTime" TransformationClaimType="firstDateTime" />
          <InputClaim ClaimTypeReferenceId="endDateTime" TransformationClaimType="secondDateTime" />
        </InputClaims>
        <InputParameters>
          <InputParameter Id="operator" DataType="string" Value="later than" />
          <InputParameter Id="timeSpanInSeconds" DataType="int" Value="120" />
        </InputParameters>
        <OutputClaims>
          <OutputClaim ClaimTypeReferenceId="validTimespan" TransformationClaimType="result" />
        </OutputClaims>
      </ClaimsTransformation>
    </ClaimsTransformations>

 

 

 

 
Step 2: Add the Technical Profiles to get the Start Date, EndDate and Compare Times

 

 

<ClaimsProviders>
    <ClaimsProvider>
      <DisplayName>User journey timeout</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="ClaimsTransformation-GetStartDateTime">
          <DisplayName>User journey timeout GetStartDateTime</DisplayName>
          <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.ClaimsTransformationProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
          <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="startDateTime" />
          </OutputClaims>
          <OutputClaimsTransformations>
            <OutputClaimsTransformation ReferenceId="GetStartDateTime" />
          </OutputClaimsTransformations>
          <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
        </TechnicalProfile>

        <TechnicalProfile Id="ClaimsTransformation-GetEndDateTimeAndCompareTimes">
          <DisplayName>User journey timeout Get EndTimeAndCompareTimes</DisplayName>
          <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.ClaimsTransformationProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
          <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="startDateTime" />
            <OutputClaim ClaimTypeReferenceId="validTimespan" />
          </OutputClaims>
          <OutputClaimsTransformations>
            <OutputClaimsTransformation ReferenceId="GetEndDateTime" />
            <OutputClaimsTransformation ReferenceId="CompareStartAndEndTimes" />
          </OutputClaimsTransformations>
          <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>
  </ClaimsProviders>

 

 

 
Step 3: Call the GetStartTime in the Orchestration Steps in the User Journeys

 

 

<!-- Demo: Set the 'startDateTime'  claim with the current date and time-->
        <OrchestrationStep Order="1" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="ClaimsTransformation-GetStartDateTime" TechnicalProfileReferenceId="ClaimsTransformation-GetStartDateTime" />
          </ClaimsExchanges>
        </OrchestrationStep>

 

 

 
Step 4: Call the GetEndTimeAndCompareTimes Technical Profile before the required steps in the flow and add a self-asserted technical profile to redirect to the page if the timeout happens

 

 

<!-- Demo: Set the 'endDateTime' claim with the current date and time. 
                   Then compare both dates and return the 'validTimespan' claim which indicates whether the
                   user journey has been completed in the preconfigure timespan-->
        <OrchestrationStep Order="8" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="ClaimsTransformation-GetEndDateTimeAndCompareTimes" TechnicalProfileReferenceId="ClaimsTransformation-GetEndDateTimeAndCompareTimes" />
          </ClaimsExchanges>
        </OrchestrationStep>

         <OrchestrationStep Order="9" Type="ClaimsExchange">
          <Preconditions>
            <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
              <Value>validTimespan</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
          </Preconditions>
          <ClaimsExchanges>
            <ClaimsExchange Id="SelfAsserted-Timeout-Error" TechnicalProfileReferenceId="SelfAsserted-Timeout-Error" />
          </ClaimsExchanges>
        </OrchestrationStep>

 

 

 

Step 5: Test the Session Timeout user journey

 

You can test by adding a separate Relying Party for the user journey timeout. The above steps can be included in any user journeys and could be reused in TrustFrameworkExtensions.xml file.

 

I hope this post was useful and helped with a better solution of configuring a timeout during user journeys with Azure AD B2C.

 

Happy Learning!

 

Co-Authors
Version history
Last update:
‎Oct 25 2022 02:18 PM
Updated by: