azureazure-active-directoryazure-ad-b2cazure-ad-b2c-custom-policy

Azure AD B2C IEF custom sign-up policy grab query parameters


In my custom policy I am trying to grab the e-mail, given_name and surname query parameters from the URL and prefill the inputs. But it seems even if I do that I keep getting for example {QueryString:email}, therefore the default value. I am using OAUTH 2 if of any help. What am I doing wrong ?

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<TrustFrameworkPolicy
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        xmlns="http://schemas.microsoft.com/online/cpim/schemas/2013/06"
        PolicySchemaVersion="0.3.0.0"
        TenantId="yourtenant.onmicrosoft.com"
        PolicyId="B2C_1A_TrustFrameworkExtensions"
        PublicPolicyUri="http://yourtenant.onmicrosoft.com/B2C_1A_TrustFrameworkExtensions">
    
    <BasePolicy>
        <TenantId>yourtenant.onmicrosoft.com</TenantId>
        <PolicyId>B2C_1A_TrustFrameworkBase</PolicyId>
    </BasePolicy>
    
    <BuildingBlocks>
        <ClaimsSchema>
            <ClaimType Id="email">
                <DisplayName>Email Address</DisplayName>
                <DataType>string</DataType>
                <DefaultPartnerClaimTypes>
                    <Protocol Name="OAuth2" PartnerClaimType="email" />
                </DefaultPartnerClaimTypes>
                <UserHelpText>Your email address</UserHelpText>
                <UserInputType>TextBox</UserInputType>
            </ClaimType>
            
            <ClaimType Id="givenName">
                <DisplayName>Given Name</DisplayName>
                <DataType>string</DataType>
                <DefaultPartnerClaimTypes>
                    <Protocol Name="OAuth2" PartnerClaimType="given_name" />
                </DefaultPartnerClaimTypes>
                <UserHelpText>Your given name</UserHelpText>
                <UserInputType>TextBox</UserInputType>
            </ClaimType>

        </ClaimsSchema>
    </BuildingBlocks>
    
    <ClaimsProviders>
        <ClaimsProvider>
            <DisplayName>Self Asserted</DisplayName>
            <TechnicalProfiles>
                <TechnicalProfile Id="SelfAsserted-SignUp">
                    <DisplayName>User Sign-Up</DisplayName>
                    <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
                    <Metadata>
                        <Item Key="ContentDefinitionReferenceId">api.selfasserted</Item>
                        <Item Key="IncludeClaimResolvingInClaimsHandling">true</Item>
                    </Metadata>
                    <InputClaims>
                        <!-- Query String Parameters: Ensure proper case and AlwaysUseDefaultValue -->
                        <InputClaim ClaimTypeReferenceId="email" DefaultValue="{QueryString:email}" AlwaysUseDefaultValue="true" />
                        <InputClaim ClaimTypeReferenceId="givenName" DefaultValue="{QueryString:given_name}" AlwaysUseDefaultValue="true" />
                        <InputClaim ClaimTypeReferenceId="surname" DefaultValue="{QueryString:surname}" AlwaysUseDefaultValue="true" />
                        <!-- Add other query parameters here -->
                    </InputClaims>
                    <OutputClaims>
                        <OutputClaim ClaimTypeReferenceId="email" Required="true" />
                        <OutputClaim ClaimTypeReferenceId="givenName" />
                        <OutputClaim ClaimTypeReferenceId="surname" />
                        <!-- Add other output claims here -->
                    </OutputClaims>
                    <ValidationTechnicalProfiles>
                        <ValidationTechnicalProfile ReferenceId="AAD-UserWriteUsingLogonEmail" />
                    </ValidationTechnicalProfiles>
                </TechnicalProfile>
            </TechnicalProfiles>
        </ClaimsProvider>
        
        <ClaimsProvider>
            <DisplayName>Azure Active Directory</DisplayName>
            <TechnicalProfiles>
                <TechnicalProfile Id="AAD-UserWriteUsingLogonEmail">
                    <DisplayName>Write user to Azure AD B2C using email</DisplayName>
                    <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.AzureActiveDirectory.AzureActiveDirectoryIdentityProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
                    <Metadata>
                        <Item Key="Operation">Write</Item>
                        <Item Key="RaiseErrorIfClaimsPrincipalAlreadyExists">true</Item>
                        <Item Key="UserMessageIfClaimsPrincipalAlreadyExists">An account with this email already exists.</Item>
                    </Metadata>
                    <InputClaims>
                        <InputClaim ClaimTypeReferenceId="email" PartnerClaimType="signInNames.emailAddress" Required="true" />
                        <InputClaim ClaimTypeReferenceId="givenName" />
                        <InputClaim ClaimTypeReferenceId="surname" />
                    </InputClaims>
                    <PersistedClaims>
                        <PersistedClaim ClaimTypeReferenceId="email" PartnerClaimType="signInNames.emailAddress" />
                        <PersistedClaim ClaimTypeReferenceId="givenName" />
                        <PersistedClaim ClaimTypeReferenceId="surname" />
                    </PersistedClaims>
                    <OutputClaims>
                        <OutputClaim ClaimTypeReferenceId="objectId" />
                    </OutputClaims>
                </TechnicalProfile>
            </TechnicalProfiles>
        </ClaimsProvider>
    </ClaimsProviders>

    <!-- User Journeys -->
    <UserJourneys>
        <UserJourney Id="SignUpJourney">
            <OrchestrationSteps>
                <OrchestrationStep Order="1" Type="ClaimsExchange">
                    <ClaimsExchanges>
                        <ClaimsExchange Id="SelfAsserted-SignUp" TechnicalProfileReferenceId="SelfAsserted-SignUp" />
                    </ClaimsExchanges>
                </OrchestrationStep>
                
                <OrchestrationStep Order="2" Type="ClaimsExchange">
                    <ClaimsExchanges>
                        <ClaimsExchange Id="AADUserWrite" TechnicalProfileReferenceId="AAD-UserWriteUsingLogonEmail" />
                    </ClaimsExchanges>
                </OrchestrationStep>
                
                <OrchestrationStep Order="3" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
            </OrchestrationSteps>
        </UserJourney>
    </UserJourneys>
    
    <RelyingParty>
        <DefaultUserJourney ReferenceId="SignUpJourney" />
        <TechnicalProfile Id="PolicyProfile">
            <DisplayName>Sign Up Policy</DisplayName>
            <Protocol Name="OpenIdConnect" />
            <OutputClaims>
                <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub" />
                <OutputClaim ClaimTypeReferenceId="email" />
                <OutputClaim ClaimTypeReferenceId="givenName" />
                <OutputClaim ClaimTypeReferenceId="surname" />
            </OutputClaims>
            <SubjectNamingInfo ClaimType="sub" />
        </TechnicalProfile>
    </RelyingParty>

</TrustFrameworkPolicy>

Solution

  • You don't access query string parameters using a QueryString claims resolver.

    You have to use OAuth-KV. So if the query string parameter is &given_name=John then {OAuth-KV:given_name} would populate John in the givenName claim in your example.