Reputation: 2373
IN our forgot password flow, I want to do a REST API call to do a validation check on the account. We have a database that we need to do a check against.
During this process, the API will return a 200 or 400.
If its a 200, I want them to continue on with the orchestration of forgot password.
If it is a 400, instead of pulling them out of the flow and putting them back in the application, I would rather show them that there is a problem with their account and to contact our support or to register a new account.
However, no matter what the response, in my current code it is send them along in the orchestration step.
This is the orchestration step:
<OrchestrationStep Order="2" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="GetMemberClaimsExchange" TechnicalProfileReferenceId="MemberAccountHolderCollector" />
</ClaimsExchanges>
</OrchestrationStep>
then this is my claims provider.
<ClaimsProvider>
<DisplayName>REST API to Check Member Status</DisplayName>
<TechnicalProfiles>
<TechnicalProfile Id="MemberAccountHolderCollector">
<DisplayName>Collect Member Info Technical Profile</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.register</Item>
</Metadata>
<ValidationTechnicalProfiles>
<ValidationTechnicalProfile ReferenceId="REST-CheckMemberAccountHolder" ContinueOnError="true"/>
</ValidationTechnicalProfiles>
</TechnicalProfile>
<TechnicalProfile Id="REST-CheckMemberAccountHolder">
<DisplayName>Rest API call to Check Member status</DisplayName>
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<Metadata>
<Item Key="ServiceUrl">{API}</Item>
<Item Key="SendClaimsIn">QueryString</Item>
<Item Key="AuthenticationType">None</Item>
<Item Key="AllowInsecureAuthInProduction">true</Item>
</Metadata>
<InputClaims>
<InputClaim ClaimTypeReferenceId="email" PartnerClaimType="emailaddress"/>
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="emailaddress" />
</OutputClaims>
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>
</ClaimsProviders>
The api.selfasserted.register is simply a template i created. I don't need to use it. I could just throw the error on the screen as anything, but I was just trying anything to get it to work.
Any help is appreciated here.
Edit:
Thank you for the advice, so i think i understand where your going.
I added a claim type
<ClaimType Id="requireRegister">
<DisplayName>requireRegster</DisplayName>
<DataType>boolean</DataType>
<UserInputType>Paragraph</UserInputType>
</ClaimType>
The idea would be that I can do an output claim.
The problem is when i do this...
<TechnicalProfiles>
<TechnicalProfile Id="MemberAccountHolderCollector">
<DisplayName>Collect Member Info Technical Profile</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.register</Item>
</Metadata>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="requireRegister" DefaultValue="true"/>
</OutputClaims>
<ValidationTechnicalProfiles>
<ValidationTechnicalProfile ReferenceId="REST-CheckMemberAccountHolder" ContinueOnError="true"/>
</ValidationTechnicalProfiles>
</TechnicalProfile>
It shows the page every time, which i don't want to do either...
Edit 2:
Our forgot password is done off this policy [enter link description here][1] [1]: https://learn.microsoft.com/en-us/azure/active-directory-b2c/add-password-reset-policy?pivots=b2c-custom-policy
in our policy when you click the forgot password button it invokes the subjourney
<SubJourneys>
<SubJourney Id="PasswordReset" Type="Call">
<OrchestrationSteps>
<!-- Validate user's email address. -->
<OrchestrationStep Order="1" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="PasswordResetUsingEmailAddressExchange" TechnicalProfileReferenceId="LocalAccountDiscoveryUsingEmailAddress" />
</ClaimsExchanges>
</OrchestrationStep>
<!-- Show TOU-->
<OrchestrationStep Order="2" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="SelfAssertedConsentExchange" TechnicalProfileReferenceId="SelfAsserted-PasswordResetConsent" />
</ClaimsExchanges>
</OrchestrationStep>
There is a custom page to show our TOU consent, before they get there, I need the account to run through our validation before.
Edit 3:
Doing the code below skips the Email validation step in the forgot password policy.
<ClaimsProvider>
<DisplayName>REST API to Check Member</DisplayName>
<TechnicalProfiles>
<TechnicalProfile Id="LocalAccountDiscoveryUsingEmailAddress">
<ValidationTechnicalProfiles>
<ValidationTechnicalProfile ReferenceId="REST-CheckMemberAccount" ContinueOnError="false"/>
</ValidationTechnicalProfiles>
</TechnicalProfile>
<!--Not using anymore -->
<TechnicalProfile Id="MemberAccountHolderCollector">
<DisplayName>Collect Member Info Technical Profile</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.register</Item>
</Metadata>
<ValidationTechnicalProfiles>
<ValidationTechnicalProfile ReferenceId="REST-CheckMemberAccount" ContinueOnError="false"/>
</ValidationTechnicalProfiles>
</TechnicalProfile>
<TechnicalProfile Id="REST-CheckMemberAccount">
<DisplayName>Rest API call to Check Member status</DisplayName>
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<Metadata>
<Item Key="ServiceUrl">{API}</Item>
<Item Key="SendClaimsIn">QueryString</Item>
<Item Key="AuthenticationType">None</Item>
<Item Key="AllowInsecureAuthInProduction">true</Item>
</Metadata>
<InputClaims>
<InputClaim ClaimTypeReferenceId="email" PartnerClaimType="emailaddress"/>
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="emailaddress" />
</OutputClaims>
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>
Upvotes: 1
Views: 869
Reputation: 11315
This configuration, where there are no output claims as part of a selfAsserted technical profile, will cause B2C to skip this entire step.
You should be adding this as a validation technical profile on the previous step, where the user enters and validates their email. As follows:
<TechnicalProfile Id="LocalAccountDiscoveryUsingEmailAddress">
<DisplayName>Reset password using email address</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.localaccountpasswordreset</Item>
<Item Key="UserMessageIfClaimsTransformationBooleanValueIsNotEqual">Your account has been locked. Contact your support person to unlock it, then try again.</Item>
</Metadata>
<CryptographicKeys>
<Key Id="issuer_secret" StorageReferenceId="B2C_1A_TokenSigningKeyContainer" />
</CryptographicKeys>
<IncludeInSso>false</IncludeInSso>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="Verified.Email" Required="true" />
<OutputClaim ClaimTypeReferenceId="objectId" />
<OutputClaim ClaimTypeReferenceId="userPrincipalName" />
<OutputClaim ClaimTypeReferenceId="authenticationSource" />
<OutputClaim ClaimTypeReferenceId="requireRegister" DefaultValue="true"/>
</OutputClaims>
<ValidationTechnicalProfiles>
<ValidationTechnicalProfile ReferenceId="AAD-UserReadUsingEmailAddress" />
<ValidationTechnicalProfile ReferenceId="MemberAccountHolderCollector" />
</ValidationTechnicalProfiles>
</TechnicalProfile>
Remove MemberAccountHolderCollector
technical profile entirely. And any reference to that from your User Journey.
Now after the user validates their email, and submits the page, the REST API will be called. If it returns an error, it is displayed on the same screen where the user validated their email.
You must return a HTTP 409 conflict with proper error JSON payload for it to be displayed on the screen. https://learn.microsoft.com/en-us/azure/active-directory-b2c/restful-technical-profile#returning-validation-error-message
Upvotes: 2