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>
<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>
<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.