Default value for extension property does not get persisted

metalheart 361 Reputation points
2023-05-26T07:47:24.19+00:00

I'd like to collect marketing consent from user on sign-up, but the extended property value doesn't get persisted into the directory when the value is unchecked, despite using a default value. What am I doing wrong?

  • Claim+user input type (TrustFrameworkExtensions.xml):
<ClaimType Id="extension_marketingOptIn">
  <DataType>string</DataType>
  <UserInputType>CheckboxMultiSelect</UserInputType>
  <Restriction>
    <Enumeration Text="I consent to receive marketing communication." Value="true" SelectByDefault="true" />
  </Restriction>
</ClaimType>
  • Claim value collection from user in a customized sign up profile (TrustFrameworkExtensions.xml):
<TechnicalProfile Id="LocalAccountSignUpWithLogonEmail-Override">
  ...
  <OutputClaims>
    ...
    <OutputClaim ClaimTypeReferenceId="extension_marketingOptIn" DefaultValue="false" />
  </OutputClaims>
  <ValidationTechnicalProfiles>
    <ValidationTechnicalProfile ReferenceId="AAD-UserWriteUsingLogonEmail" />
  </ValidationTechnicalProfiles>
</TechnicalProfile>
  • Persisting and reading claim value (TrustFrameworkExtensions.xml):
<TechnicalProfile Id="AAD-UserWriteUsingLogonEmail">
  <PersistedClaims>
    <PersistedClaim ClaimTypeReferenceId="extension_marketingOptIn" />
  </PersistedClaims>
</TechnicalProfile>
<TechnicalProfile Id="AAD-UserReadUsingObjectId">
  <OutputClaims>
    <OutputClaim ClaimTypeReferenceId="extension_marketingOptIn" />
  </OutputClaims>
</TechnicalProfile>
  • Sign-up user journey:
    <UserJourney Id="SignUp-LocalOnly">
      <OrchestrationSteps>
        <OrchestrationStep Order="1" Type="ClaimsProviderSelection" ContentDefinitionReferenceId="api.idpselections.signup">
          <ClaimsProviderSelections>
            <ClaimsProviderSelection TargetClaimsExchangeId="SignUpWithLogonEmailExchange" />
          </ClaimsProviderSelections>
        </OrchestrationStep>
        
        <OrchestrationStep Order="2" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="SignUpWithLogonEmailExchange" TechnicalProfileReferenceId="LocalAccountSignUpWithLogonEmail-Override" />
          </ClaimsExchanges>
        </OrchestrationStep>

        <OrchestrationStep Order="3" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
      </OrchestrationSteps>
      <ClientDefinition ReferenceId="DefaultWeb" />
    </UserJourney>
  • Sign-in user journey:
    <UserJourney Id="SignIn-LocalOnly">
      <OrchestrationSteps>

        <OrchestrationStep Order="1" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin">
          <ClaimsProviderSelections>
            <ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninEmailExchange" />
          </ClaimsProviderSelections>
          <ClaimsExchanges>
            <ClaimsExchange Id="LocalAccountSigninEmailExchange" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Email" />
          </ClaimsExchanges>
        </OrchestrationStep>

        <!-- This step reads any user attributes that we may not have received when in the token. -->
        <OrchestrationStep Order="2" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
          </ClaimsExchanges>
        </OrchestrationStep>

        <OrchestrationStep Order="3" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />

      </OrchestrationSteps>
      <ClientDefinition ReferenceId="DefaultWeb" />
    </UserJourney>

When the checkbox is selected, the behavior is correct - the "true" value gets correctly persisted and I can see the claim value in the token both in sign-up and in sign-in. When the checkbox is unselected, the "false" value is supplied as a token claim on sign-up, but not persisted (verified with MS Graph query to see the extension property value), and no value is (understandably) provided in the sign-in token.

Microsoft Entra External ID
Microsoft Entra External ID
A modern identity solution for securing access to customer, citizen and partner-facing apps and services. It is the converged platform of Azure AD External Identities B2B and B2C. Replaces Azure Active Directory External Identities.
2,752 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Akshay-MSFT 17,641 Reputation points Microsoft Employee
    2023-05-29T09:38:57.89+00:00

    @metalheart

    Thank you for posting your query on Microsoft Q&A, from the above description I could understand that when consent is set to NO (No inputs) the value does not gets persisted. I assume that could be because we don't pass "Null" value for a claim.

    I would recommend tochange the Claim+user input type (TrustFrameworkExtensions.xml) and validate the behavior:

    <ClaimType Id="extension_marketingOptIn">
    <DisplayName>I consent to receive marketing communication</DisplayName>
      <DataType>string</DataType>
       <UserInputType>DropdownSingleSelect</UserInputType>
        <Restriction>
        <Enumeration Text="No" Value="false" SelectByDefault="false"/>
        <Enumeration Text="Yes" Value="true" SelectByDefault="true" />
      </Restriction>
    </ClaimType>
    
    

    Do let me know if you have any queries by responding in the comments section.

    Thanks,

    Akshay Kaushik

    Please "Accept the answer" (Yes), and share your feedback if the suggestion answers you’re your query. This will help us and others in the community as well.