'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:
So that I could get right here at the start:
----------------UPDATE--------------------------
Basically, I would have to use a InputClaimsTransformations to
- set the readOnlySignInName from OIDC:LoginHint
- 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 |
---|