Azure AD B2C custom policy set extension attribute value
up vote
0
down vote
favorite
I have B2C custom policy signin UserJouney which checks to see if the user requires a password reset on their first logon. We are using an extension attribute to do this as B2C has a bug where the "forceChangePasswordNextLogin" value prevents the user from logging in at all.
Here is the sign in user journey.
<UserJourney Id="SignUpOrSignInSaml">
<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="ClaimsExchange">
<Preconditions>
<Precondition Type="ClaimEquals" ExecuteActionsIf="false">
<Value>extension_ChangePasswordRequired</Value>
<Value>true</Value>
<Action>SkipThisOrchestrationStep</Action>
</Precondition>
</Preconditions>
<ClaimsExchanges>
<ClaimsExchange Id="NewCredentials" TechnicalProfileReferenceId="LocalAccountWritePasswordChangeUsingObjectId" />
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="5" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="UpdatePasswordResetValue" TechnicalProfileReferenceId="LocalAccountUpdatePasswordResetStateValue" />
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="6" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="Saml2AssertionIssuer" />
</OrchestrationSteps>
<ClientDefinition ReferenceId="DefaultWeb" />
</UserJourney>
Step 4 in the UserJourney evaluates whether the extension attribute "extension_ChangePasswordRequired" is set to "true" and will prompt the user to change their password if it reads "true". This is working fine.
Step 5 is then used to update the extension attribute to something other than "true" so the user isn't prompted again at next login however doesn't seem to be working.
Here is my "LocalAccountUpdatePasswordResetStateValue" TechnicalProfile
<TechnicalProfile Id="LocalAccountUpdatePasswordResetStateValue">
<DisplayName>Update Password Set Value</DisplayName>
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="extension_ChangePasswordRequired" Required="true" />
</OutputClaims>
<OutputClaimsTransformations>
<OutputClaimsTransformation ReferenceId="SetPasswordResetStatus" />
</OutputClaimsTransformations>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
</TechnicalProfile>
And here is the Output claims transformation that it is calling
<ClaimsTransformation Id="SetPasswordResetStatus" TransformationMethod="FormatStringClaim">
<InputClaims>
<InputClaim ClaimTypeReferenceId="extension_ChangePasswordRequired" TransformationClaimType="inputClaim" />
</InputClaims>
<InputParameters>
<InputParameter Id="stringFormat" DataType="string" Value="abc123" />
</InputParameters>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="extension_ChangePasswordRequired" TransformationClaimType="outputClaim" />
</OutputClaims>
</ClaimsTransformation>
The policies pass validation at time of upload however doesn't set the extension attribute on the user after a password reset.
Does anyone know what I'm doing wrong here or if there is a better way of achieving this?
-----Update-----
I'm successfully able to write a value to a different extension attribute via a persisted claim as seen here
<TechnicalProfile Id="AAD-UserUpdateStateValue">
<Metadata>
<Item Key="Operation">Write</Item>
<Item Key="RaiseErrorIfClaimsPrincipalAlreadyExists">false</Item>
<Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">true</Item>
</Metadata>
<IncludeInSso>false</IncludeInSso>
<InputClaims>
<InputClaim ClaimTypeReferenceId="objectId" Required="true" />
</InputClaims>
<PersistedClaims>
<!-- Required claims -->
<PersistedClaim ClaimTypeReferenceId="objectId" />
<!-- Optional claims -->
<PersistedClaim ClaimTypeReferenceId="extension_Flag" DefaultValue="abc1234567"/>
</PersistedClaims>
<IncludeTechnicalProfile ReferenceId="AAD-Common" />
</TechnicalProfile>
However as mentioned by Chris in this post this doesn't work if I have read the claim in a previous step.
azure-ad-b2c
add a comment |
up vote
0
down vote
favorite
I have B2C custom policy signin UserJouney which checks to see if the user requires a password reset on their first logon. We are using an extension attribute to do this as B2C has a bug where the "forceChangePasswordNextLogin" value prevents the user from logging in at all.
Here is the sign in user journey.
<UserJourney Id="SignUpOrSignInSaml">
<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="ClaimsExchange">
<Preconditions>
<Precondition Type="ClaimEquals" ExecuteActionsIf="false">
<Value>extension_ChangePasswordRequired</Value>
<Value>true</Value>
<Action>SkipThisOrchestrationStep</Action>
</Precondition>
</Preconditions>
<ClaimsExchanges>
<ClaimsExchange Id="NewCredentials" TechnicalProfileReferenceId="LocalAccountWritePasswordChangeUsingObjectId" />
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="5" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="UpdatePasswordResetValue" TechnicalProfileReferenceId="LocalAccountUpdatePasswordResetStateValue" />
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="6" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="Saml2AssertionIssuer" />
</OrchestrationSteps>
<ClientDefinition ReferenceId="DefaultWeb" />
</UserJourney>
Step 4 in the UserJourney evaluates whether the extension attribute "extension_ChangePasswordRequired" is set to "true" and will prompt the user to change their password if it reads "true". This is working fine.
Step 5 is then used to update the extension attribute to something other than "true" so the user isn't prompted again at next login however doesn't seem to be working.
Here is my "LocalAccountUpdatePasswordResetStateValue" TechnicalProfile
<TechnicalProfile Id="LocalAccountUpdatePasswordResetStateValue">
<DisplayName>Update Password Set Value</DisplayName>
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="extension_ChangePasswordRequired" Required="true" />
</OutputClaims>
<OutputClaimsTransformations>
<OutputClaimsTransformation ReferenceId="SetPasswordResetStatus" />
</OutputClaimsTransformations>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
</TechnicalProfile>
And here is the Output claims transformation that it is calling
<ClaimsTransformation Id="SetPasswordResetStatus" TransformationMethod="FormatStringClaim">
<InputClaims>
<InputClaim ClaimTypeReferenceId="extension_ChangePasswordRequired" TransformationClaimType="inputClaim" />
</InputClaims>
<InputParameters>
<InputParameter Id="stringFormat" DataType="string" Value="abc123" />
</InputParameters>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="extension_ChangePasswordRequired" TransformationClaimType="outputClaim" />
</OutputClaims>
</ClaimsTransformation>
The policies pass validation at time of upload however doesn't set the extension attribute on the user after a password reset.
Does anyone know what I'm doing wrong here or if there is a better way of achieving this?
-----Update-----
I'm successfully able to write a value to a different extension attribute via a persisted claim as seen here
<TechnicalProfile Id="AAD-UserUpdateStateValue">
<Metadata>
<Item Key="Operation">Write</Item>
<Item Key="RaiseErrorIfClaimsPrincipalAlreadyExists">false</Item>
<Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">true</Item>
</Metadata>
<IncludeInSso>false</IncludeInSso>
<InputClaims>
<InputClaim ClaimTypeReferenceId="objectId" Required="true" />
</InputClaims>
<PersistedClaims>
<!-- Required claims -->
<PersistedClaim ClaimTypeReferenceId="objectId" />
<!-- Optional claims -->
<PersistedClaim ClaimTypeReferenceId="extension_Flag" DefaultValue="abc1234567"/>
</PersistedClaims>
<IncludeTechnicalProfile ReferenceId="AAD-Common" />
</TechnicalProfile>
However as mentioned by Chris in this post this doesn't work if I have read the claim in a previous step.
azure-ad-b2c
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I have B2C custom policy signin UserJouney which checks to see if the user requires a password reset on their first logon. We are using an extension attribute to do this as B2C has a bug where the "forceChangePasswordNextLogin" value prevents the user from logging in at all.
Here is the sign in user journey.
<UserJourney Id="SignUpOrSignInSaml">
<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="ClaimsExchange">
<Preconditions>
<Precondition Type="ClaimEquals" ExecuteActionsIf="false">
<Value>extension_ChangePasswordRequired</Value>
<Value>true</Value>
<Action>SkipThisOrchestrationStep</Action>
</Precondition>
</Preconditions>
<ClaimsExchanges>
<ClaimsExchange Id="NewCredentials" TechnicalProfileReferenceId="LocalAccountWritePasswordChangeUsingObjectId" />
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="5" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="UpdatePasswordResetValue" TechnicalProfileReferenceId="LocalAccountUpdatePasswordResetStateValue" />
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="6" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="Saml2AssertionIssuer" />
</OrchestrationSteps>
<ClientDefinition ReferenceId="DefaultWeb" />
</UserJourney>
Step 4 in the UserJourney evaluates whether the extension attribute "extension_ChangePasswordRequired" is set to "true" and will prompt the user to change their password if it reads "true". This is working fine.
Step 5 is then used to update the extension attribute to something other than "true" so the user isn't prompted again at next login however doesn't seem to be working.
Here is my "LocalAccountUpdatePasswordResetStateValue" TechnicalProfile
<TechnicalProfile Id="LocalAccountUpdatePasswordResetStateValue">
<DisplayName>Update Password Set Value</DisplayName>
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="extension_ChangePasswordRequired" Required="true" />
</OutputClaims>
<OutputClaimsTransformations>
<OutputClaimsTransformation ReferenceId="SetPasswordResetStatus" />
</OutputClaimsTransformations>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
</TechnicalProfile>
And here is the Output claims transformation that it is calling
<ClaimsTransformation Id="SetPasswordResetStatus" TransformationMethod="FormatStringClaim">
<InputClaims>
<InputClaim ClaimTypeReferenceId="extension_ChangePasswordRequired" TransformationClaimType="inputClaim" />
</InputClaims>
<InputParameters>
<InputParameter Id="stringFormat" DataType="string" Value="abc123" />
</InputParameters>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="extension_ChangePasswordRequired" TransformationClaimType="outputClaim" />
</OutputClaims>
</ClaimsTransformation>
The policies pass validation at time of upload however doesn't set the extension attribute on the user after a password reset.
Does anyone know what I'm doing wrong here or if there is a better way of achieving this?
-----Update-----
I'm successfully able to write a value to a different extension attribute via a persisted claim as seen here
<TechnicalProfile Id="AAD-UserUpdateStateValue">
<Metadata>
<Item Key="Operation">Write</Item>
<Item Key="RaiseErrorIfClaimsPrincipalAlreadyExists">false</Item>
<Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">true</Item>
</Metadata>
<IncludeInSso>false</IncludeInSso>
<InputClaims>
<InputClaim ClaimTypeReferenceId="objectId" Required="true" />
</InputClaims>
<PersistedClaims>
<!-- Required claims -->
<PersistedClaim ClaimTypeReferenceId="objectId" />
<!-- Optional claims -->
<PersistedClaim ClaimTypeReferenceId="extension_Flag" DefaultValue="abc1234567"/>
</PersistedClaims>
<IncludeTechnicalProfile ReferenceId="AAD-Common" />
</TechnicalProfile>
However as mentioned by Chris in this post this doesn't work if I have read the claim in a previous step.
azure-ad-b2c
I have B2C custom policy signin UserJouney which checks to see if the user requires a password reset on their first logon. We are using an extension attribute to do this as B2C has a bug where the "forceChangePasswordNextLogin" value prevents the user from logging in at all.
Here is the sign in user journey.
<UserJourney Id="SignUpOrSignInSaml">
<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="ClaimsExchange">
<Preconditions>
<Precondition Type="ClaimEquals" ExecuteActionsIf="false">
<Value>extension_ChangePasswordRequired</Value>
<Value>true</Value>
<Action>SkipThisOrchestrationStep</Action>
</Precondition>
</Preconditions>
<ClaimsExchanges>
<ClaimsExchange Id="NewCredentials" TechnicalProfileReferenceId="LocalAccountWritePasswordChangeUsingObjectId" />
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="5" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="UpdatePasswordResetValue" TechnicalProfileReferenceId="LocalAccountUpdatePasswordResetStateValue" />
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="6" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="Saml2AssertionIssuer" />
</OrchestrationSteps>
<ClientDefinition ReferenceId="DefaultWeb" />
</UserJourney>
Step 4 in the UserJourney evaluates whether the extension attribute "extension_ChangePasswordRequired" is set to "true" and will prompt the user to change their password if it reads "true". This is working fine.
Step 5 is then used to update the extension attribute to something other than "true" so the user isn't prompted again at next login however doesn't seem to be working.
Here is my "LocalAccountUpdatePasswordResetStateValue" TechnicalProfile
<TechnicalProfile Id="LocalAccountUpdatePasswordResetStateValue">
<DisplayName>Update Password Set Value</DisplayName>
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="extension_ChangePasswordRequired" Required="true" />
</OutputClaims>
<OutputClaimsTransformations>
<OutputClaimsTransformation ReferenceId="SetPasswordResetStatus" />
</OutputClaimsTransformations>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
</TechnicalProfile>
And here is the Output claims transformation that it is calling
<ClaimsTransformation Id="SetPasswordResetStatus" TransformationMethod="FormatStringClaim">
<InputClaims>
<InputClaim ClaimTypeReferenceId="extension_ChangePasswordRequired" TransformationClaimType="inputClaim" />
</InputClaims>
<InputParameters>
<InputParameter Id="stringFormat" DataType="string" Value="abc123" />
</InputParameters>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="extension_ChangePasswordRequired" TransformationClaimType="outputClaim" />
</OutputClaims>
</ClaimsTransformation>
The policies pass validation at time of upload however doesn't set the extension attribute on the user after a password reset.
Does anyone know what I'm doing wrong here or if there is a better way of achieving this?
-----Update-----
I'm successfully able to write a value to a different extension attribute via a persisted claim as seen here
<TechnicalProfile Id="AAD-UserUpdateStateValue">
<Metadata>
<Item Key="Operation">Write</Item>
<Item Key="RaiseErrorIfClaimsPrincipalAlreadyExists">false</Item>
<Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">true</Item>
</Metadata>
<IncludeInSso>false</IncludeInSso>
<InputClaims>
<InputClaim ClaimTypeReferenceId="objectId" Required="true" />
</InputClaims>
<PersistedClaims>
<!-- Required claims -->
<PersistedClaim ClaimTypeReferenceId="objectId" />
<!-- Optional claims -->
<PersistedClaim ClaimTypeReferenceId="extension_Flag" DefaultValue="abc1234567"/>
</PersistedClaims>
<IncludeTechnicalProfile ReferenceId="AAD-Common" />
</TechnicalProfile>
However as mentioned by Chris in this post this doesn't work if I have read the claim in a previous step.
azure-ad-b2c
azure-ad-b2c
edited yesterday
asked yesterday
Brady
133
133
add a comment |
add a comment |
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53237370%2fazure-ad-b2c-custom-policy-set-extension-attribute-value%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password