'AAD B2C custom policy read without user interaction

Is it possible to make a read operation before any other in a TechnicalProfile? In a password reset scenario where users always login with a username, I'd like to read the email and display it right on the landing page of the user journey. Every sample I see uses a previous step in which we only display the username claim and, on the button click, in a ValidationProfile, the read occurs. So it's only in the next step that you see the email and can click to validate it. It's not optimal as it adds a useless step.

So to be clear, the policy receives the identifier (a 6 digits ID) via LoginHint and I would like to read the email from AAD (with an AzureActiveDirectoryProvider like AAD-Common profile) and show it in a Verified.Email claim right off the bat. No user interaction needed. Anyone have an idea on how could I do it?

The first step that I want to get rid of: enter image description here

So that I could get right here at the start: enter image description here

----------------UPDATE--------------------------

Basically, I would have to use a InputClaimsTransformations to

  1. set the readOnlySignInName from OIDC:LoginHint
  2. call “AAD-UserReadUsingUserNameAndGetStrongAuthenticationEmailAddress” technical profile which uses AAD-Common (AzureActiveDirectoryProvider) to read from AAD using the readOnlySignInName claim.

So, I would need to “call” a “Claims transformation technical profile”. But such technical profiles seem to be available only for OutputClaimsTransformations (as specified here).

Here is the AAD-UserReadUsingUserNameAndGetStrongAuthenticationEmailAddress profile that reads from AAD to get the actual objectId and email for the LocalAccountDiscoveryUsingUserNameAndValidateStrongAuthenticationEmailAddressTest profile, which is the first step of the UserJourney :


<TechnicalProfile Id="AAD-UserReadUsingUserNameAndGetStrongAuthenticationEmailAddressTest">
          <Metadata>
            <Item Key="Operation">Read</Item>
            <Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">true</Item>
            <Item Key="IncludeClaimResolvingInClaimsHandling">true</Item>
          </Metadata>
          <InputClaims>
            <InputClaim ClaimTypeReferenceId="readOnlySignInName" DefaultValue="{OIDC:LoginHint}" AlwaysUseDefaultValue="true" PartnerClaimType="signInNames.userName" Required="true" />
          </InputClaims>
          <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="objectId" />
            <OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="localAccountAuthentication" />
            <OutputClaim ClaimTypeReferenceId="strongAuthenticationEmailAddress" />
          </OutputClaims>
          <IncludeTechnicalProfile ReferenceId="AAD-Common" />
        </TechnicalProfile>

<TechnicalProfile Id="LocalAccountDiscoveryUsingUserNameAndValidateStrongAuthenticationEmailAddressTest">
          <DisplayName>Reset password using username</DisplayName>
          <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
          <Metadata>
            <!-- Other values maybe defined in localized api.selfasserted.fr and api.selfasserted.en -->
            <Item Key="IpAddressClaimReferenceId">IpAddress</Item>
            <Item Key="ContentDefinitionReferenceId">api.localaccountpasswordreset</Item>
            <Item Key="AllowGenerationOfClaimsWithNullValues">true</Item>
            <Item Key="UserMessageIfClaimsTransformationStringsAreNotEqual">An account could not be found for the provided User ID and email combination.</Item>
            <Item Key="UserMessageIfClaimsTransformationBooleanValueIsNotEqual">Your account has been locked. Contact your support person to unlock it, then try again.</Item>
            <Item Key="LocalAccountType">Username</Item>
            <Item Key="LocalAccountProfile">true</Item>
            <!-- Reduce the default self-asserted retry limit of 7 for the reset journey -->
            <Item Key="setting.retryLimit">5</Item>
          </Metadata>
          <CryptographicKeys>
            <Key Id="issuer_secret" StorageReferenceId="B2C_1A_TokenSigningKeyContainer" />
          </CryptographicKeys>
          <InputClaimsTransformations>
            <!-- This is what I'm trying to do, read the user to get email address -->
            <InputClaimsTransformation ReferenceId="AAD-UserReadUsingUserNameAndGetStrongAuthenticationEmailAddressTest" />
            <!-- Copy this address to a readonly field for display. This part works fine. -->
            <InputClaimsTransformation ReferenceId="CopySignInEmailAddressToEmail" />
          </InputClaimsTransformations>
          <InputClaims>
            <InputClaim ClaimTypeReferenceId="readOnlySignInName" />
            <InputClaim ClaimTypeReferenceId="emailFromAAD" />
          </InputClaims>
          <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="readOnlySignInName" Required="true" />
            <OutputClaim ClaimTypeReferenceId="emailFromAAD" PartnerClaimType="Verified.Email" Required="true" />
            <OutputClaim ClaimTypeReferenceId="authenticationSource" />
          </OutputClaims>
          <OutputClaimsTransformations>
            <OutputClaimsTransformation ReferenceId="CopySignInNameFromReadOnly" />
          </OutputClaimsTransformations>
          <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
        </TechnicalProfile>




Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source