Search code examples
azure-ad-b2cclaimsresolver

How to use a claim resolver in Persisted claims?


I would like to store the last login time in an extension field whenever user is logged in. I have created a technical profile like below and call it from an orchestration step. My problem is that it is not resolving the {Context:DateTimeInUtc}, instead it writes the word {Context:DateTimeInUtc} in to the attribute.

    <TechnicalProfile Id="Custom-TP-AAD-UpdateLastLoginDate-UsingObjectId">
     <Metadata>
      <Item Key="Operation">Write</Item>
      <Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">true</Item>
     </Metadata>
     <IncludeInSso>false</IncludeInSso>
     <InputClaims>
      <InputClaim ClaimTypeReferenceId="objectId" Required="true" />
     </InputClaims>
     <PersistedClaims>
      <PersistedClaim ClaimTypeReferenceId="objectId" />
      <PersistedClaim ClaimTypeReferenceId="extension_LastLoginDate" PartnerClaimType="{Context:DateTimeInUtc}" />
     </PersistedClaims>
     <IncludeTechnicalProfile ReferenceId="AAD-Common" />
    </TechnicalProfile>

What am I doing wrong?


Solution

  • I was finally able to do it using claim transformation .
    As per Microsoft claim resolver can not be used with Persisted claims as of now. They are working to enable this feature for more technical profile types.

    Here is the detailed steps to do it.

    Step 1 : First add two claims

        <ClaimType Id="extension_LastLoginDate">
            <DisplayName>last time user logged in</DisplayName>
            <DataType>dateTime</DataType>
            <UserHelpText>last time user logged in</UserHelpText>
          </ClaimType>
          <ClaimType Id="CurrentTime">
            <DisplayName>Current time</DisplayName>
            <DataType>dateTime</DataType>
            <UserHelpText>Current time</UserHelpText>
          </ClaimType>
    

    First one is extension attribute which is used to store the value in AD. Second one is a temporary variable to hold the current date time.

    Step 2 : Add new claims transformation, this is needed to get current data time (utc) in CurrentTime claim

    
          <ClaimsTransformation Id="GetSystemDateTime" TransformationMethod="GetCurrentDateTime">
            <OutputClaims>
              <OutputClaim ClaimTypeReferenceId="CurrentTime" TransformationClaimType="currentDateTime" />
            </OutputClaims>
          </ClaimsTransformation>
    

    Step 3 : Define a technical profile to update the extension_LastLoginDate attribute

            <TechnicalProfile Id="Custom-TP-AAD-WriteLastLoginDateUsingObjectId">
              <Metadata>
                <Item Key="Operation">Write</Item>
                <Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">true</Item>
              </Metadata>
              <IncludeInSso>false</IncludeInSso>
              <InputClaims>
                <InputClaim ClaimTypeReferenceId="objectId" Required="true" />
              </InputClaims>
              <PersistedClaims>
                <PersistedClaim ClaimTypeReferenceId="objectId" />
                <PersistedClaim ClaimTypeReferenceId="CurrentTime" PartnerClaimType="extension_LastLoginDate" />
              </PersistedClaims>
              <IncludeTechnicalProfile ReferenceId="AAD-Common" />
            </TechnicalProfile>
    

    Steps 4 : Update existing technical profile AAD-UserReadUsingObjectId. This is an important step where you are going to call claims transformation and add CurrentTime claim in claim bag. I have used AAD-UserReadUsingObjectId technical profile but it can be any other technical profile as long as it is ensured that claims transformation has been called and CurrentTime claim is added to claims bag.

            <TechnicalProfile Id="AAD-UserReadUsingObjectId">
              <Metadata>
                <Item Key="Operation">Read</Item>
                <Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">true</Item>
              </Metadata>
              <IncludeInSso>false</IncludeInSso>
              <InputClaims>
                <InputClaim ClaimTypeReferenceId="objectId" Required="true" />
              </InputClaims>
              <OutputClaims>
                <OutputClaim ClaimTypeReferenceId="signInNames.emailAddress" />
                <OutputClaim ClaimTypeReferenceId="displayName" />
                <OutputClaim ClaimTypeReferenceId="objectId" />
                <OutputClaim ClaimTypeReferenceId="CurrentTime" />
              </OutputClaims>
              <OutputClaimsTransformations>
                <OutputClaimsTransformation ReferenceId="GetSystemDateTime" />
              </OutputClaimsTransformations>
              <IncludeTechnicalProfile ReferenceId="AAD-Common" />
            </TechnicalProfile>
    

    Step 5 : Finally you can call Custom-TP-AAD-WriteLastLoginDateUsingObjectIdtechnical profile from one of the OrchestrationStep in any user journey

            <OrchestrationStep Order="5" Type="ClaimsExchange">
              <ClaimsExchanges>
                <ClaimsExchange Id="WriteLastLogonTime" TechnicalProfileReferenceId="Custom-TP-AAD-WriteLastLoginDateUsingObjectId" />
              </ClaimsExchanges>
            </OrchestrationStep>