10

What do I have to change in the custom policy starter pack to make my sign-in/sing-up's policy username based not email based?

spottedmahn
  • 14,823
  • 13
  • 108
  • 178

1 Answers1

8

Add this technical profile to TrustFrameworkExtensions.xml to write the user to Azure AD

<TechnicalProfile Id="AAD-UserWriteUsingLogonName">
    <Metadata>
        <Item Key="Operation">Write</Item>
        <Item Key="RaiseErrorIfClaimsPrincipalAlreadyExists">true</Item>
    </Metadata>
    <InputClaims>
        <InputClaim ClaimTypeReferenceId="signInName" PartnerClaimType="signInNames.userName" Required="true" />
    </InputClaims>
    <PersistedClaims>
        <PersistedClaim ClaimTypeReferenceId="signInName" PartnerClaimType="signInNames.userName" />
        <PersistedClaim ClaimTypeReferenceId="email" PartnerClaimType="strongAuthenticationEmailAddress" />
        <PersistedClaim ClaimTypeReferenceId="newPassword" PartnerClaimType="password" />
        <PersistedClaim ClaimTypeReferenceId="displayName" DefaultValue="SomeDefaultDisplayNameValue" />
    </PersistedClaims>
    <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="objectId" />
        <OutputClaim ClaimTypeReferenceId="newUser" PartnerClaimType="newClaimsPrincipalCreated" />
        <OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="localAccountAuthentication" />
        <OutputClaim ClaimTypeReferenceId="userPrincipalName" />
    </OutputClaims>
    <IncludeTechnicalProfile ReferenceId="AAD-Common" />
    <UseTechnicalProfileForSessionManagement ReferenceId="SM-AAD" />
</TechnicalProfile>

Add this technical profile to TrustFrameworkExtensions.xml that is called by the user journey. The critical change here is the <Item Key="LocalAccountType">Username</Item> and <Item Key="LocalAccountProfile">true</Item>

<TechnicalProfile Id="LocalAccountSignUpWithLogonName">
    <DisplayName>User ID signup</DisplayName>
    <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    <Metadata>
        <Item Key="IpAddressClaimReferenceId">IpAddress</Item>
        <Item Key="ContentDefinitionReferenceId">api.localaccountsignup</Item>
        <Item Key="LocalAccountType">Username</Item>
        <Item Key="LocalAccountProfile">true</Item>
        <Item Key="language.button_continue">Create</Item>
    </Metadata>
    <CryptographicKeys>
        <Key Id="issuer_secret" StorageReferenceId="B2C_1A_TokenSigningKeyContainer" />
    </CryptographicKeys>
    <InputClaims>
        <InputClaim ClaimTypeReferenceId="signInName" />
    </InputClaims>
    <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="objectId" Required="true" />
        <OutputClaim ClaimTypeReferenceId="signInName" Required="true" />
        <OutputClaim ClaimTypeReferenceId="newPassword" Required="true" />
        <OutputClaim ClaimTypeReferenceId="reenterPassword" Required="true" />
        <OutputClaim ClaimTypeReferenceId="email" Required="true" />
        <OutputClaim ClaimTypeReferenceId="executed-SelfAsserted-Input" DefaultValue="true" />
        <OutputClaim ClaimTypeReferenceId="newUser" />
        <OutputClaim ClaimTypeReferenceId="authenticationSource" />
        <OutputClaim ClaimTypeReferenceId="userPrincipalName" />
    </OutputClaims>
    <ValidationTechnicalProfiles>
        <ValidationTechnicalProfile ReferenceId="AAD-UserWriteUsingLogonName" />
    </ValidationTechnicalProfiles>
    <UseTechnicalProfileForSessionManagement ReferenceId="SM-AAD" />
</TechnicalProfile>

Sigin Technical Profile for Reference

<TechnicalProfile Id="SelfAsserted-LocalAccountSignin-Username">
    <DisplayName>Local Account Signin</DisplayName>
    <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    <Metadata>
        <Item Key="SignUpTarget">SignUpWithLogonUsernameExchange</Item>
        <Item Key="setting.operatingMode">Username</Item>
        <Item Key="ContentDefinitionReferenceId">api.selfasserted</Item>
    </Metadata>
    <IncludeInSso>false</IncludeInSso>
    <InputClaims>
        <InputClaim ClaimTypeReferenceId="signInName" />
    </InputClaims>
    <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="signInName" Required="true" />
        <OutputClaim ClaimTypeReferenceId="password" Required="true" />
        <OutputClaim ClaimTypeReferenceId="objectId" />
        <OutputClaim ClaimTypeReferenceId="authenticationSource" />
    </OutputClaims>
    <ValidationTechnicalProfiles>
        <ValidationTechnicalProfile ReferenceId="login-NonInteractive" />
    </ValidationTechnicalProfiles>
    <UseTechnicalProfileForSessionManagement ReferenceId="SM-AAD" />
</TechnicalProfile>

Add this user journey to TrustFrameworkExtensions.xml

<UserJourney Id="SignUpOrSignIn">
    <OrchestrationSteps>
        <OrchestrationStep Order="1" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin">
            <ClaimsProviderSelections>
                <ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninUsernameExchange" />
            </ClaimsProviderSelections>
            <ClaimsExchanges>
                <ClaimsExchange Id="LocalAccountSigninUsernameExchange" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Username" />
            </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="2" Type="ClaimsExchange">
            <Preconditions>
                <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
                    <Value>objectId</Value>
                    <Action>SkipThisOrchestrationStep</Action>
                </Precondition>
            </Preconditions>
            <ClaimsExchanges>
                <ClaimsExchange Id="SignUpWithLogonUsernameExchange" TechnicalProfileReferenceId="LocalAccountSignUpWithLogonName" />
            </ClaimsExchanges>
        </OrchestrationStep>
        <!-- This step reads any user attributes that we may not have received when in the token. -->
        <OrchestrationStep Order="3" Type="ClaimsExchange">
            <ClaimsExchanges>
                <ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
            </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="4" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
    </OrchestrationSteps>
    <ClientDefinition ReferenceId="DefaultWeb" />
</UserJourney>

thanks to Omer for his help!

Chris Padgett
  • 14,186
  • 1
  • 15
  • 28
spottedmahn
  • 14,823
  • 13
  • 108
  • 178
  • 1
    Very nice spottedmahn! When I first saw this, it reminded me of the great work you had been doing! – Omer Iqbal Oct 05 '17 at 18:25
  • 1
    [GitHub Issue](https://github.com/Azure-Samples/active-directory-b2c-custom-policy-starterpack/issues/12) to get this included by default in the starter pack. – spottedmahn Oct 16 '17 at 12:57
  • Is that UserJourney correct? I receive an error when uploading TrustFrameworkExtensions.xml with that UserJourney: "User journey 'SignUpOrSignIn' is invalid because it contains multiple SendClaims steps.User journey "SignUpOrSignIn" in policy "B2C_1A_TrustFrameworkExtensions" of tenant "mytenant" has step 3 with 2 claims exchanges. It must be preceded by a claims provider selection in order to determine which claims exchange can be used." – Chad_C Apr 19 '18 at 17:17
  • 3
    @Chad_C This has been fixed in the above answer. I have changed the `` reference from "LocalAccountSigninEmailExchange" to "LocalAccountSigninUsernameExchange". – Chris Padgett Jul 25 '18 at 05:22
  • @ChrisPadgett UserJourneyId should be changed in order to avoid merging the default TrustFrameworkBase UserJourney, that has the same id. – m4tte0 Mar 19 '20 at 15:05