Reputation: 221
I have developed a custom policy for signup and sign-in. During subsequent sign-ins I need to perform a check against an external API if a piece of data that was collected on signup is valid. If it is not valid I need to show an error to the user.
I have already created the external API and can call it from the policy. However I am unsure how to perform this check during sign in since it isn't a custom self asserted technical profile.
I tried adding the RestfulProvider technical profile directly as an orchestration step in the user journey. While this does call my API and perform the check, my issue is this doesn't show the error on the signin screen it redirects to my app with an error_description parameter of the message returned from my API.
I want to be able to show this error nicely on the sign in screen or another B2C rendered screen instead of redirecting to my app.
My restful provider policy
<ClaimsProvider>
<DisplayName>Validate Inactive Employee</DisplayName>
<TechnicalProfiles>
<TechnicalProfile Id="REST-CheckInactiveEmployee">
<DisplayName>Check Input Data</DisplayName>
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<Metadata>
<!-- Set the ServiceUrl with your own REST API endpoint -->
<Item Key="ServiceUrl">https://NAMEOFFUNCTIONGOESHERE.azurewebsites.net/api/checksomething?code=CODEGOESHERE</Item>
<!-- Claims will be sent in the body as raw json. -->
<Item Key="SendClaimsIn">Body</Item>
<!-- Set AuthenticationType to Basic. -->
<Item Key="AuthenticationType">Basic</Item>
<!-- REMOVE the following line in production environments -->
<Item Key="AllowInsecureAuthInProduction">false</Item>
</Metadata>
<CryptographicKeys>
<!-- Username and pass to be used for basic auth with the API. -->
<Key Id="BasicAuthenticationUsername" StorageReferenceId="AUTHUSER" />
<Key Id="BasicAuthenticationPassword" StorageReferenceId="AUTHPASS" />
</CryptographicKeys>
<InputClaims>
<!-- Claims sent to your REST API -->
<InputClaim ClaimTypeReferenceId="CLAIMTOSENDTOAPI" />
</InputClaims>
<OutputClaims>
<!-- Claims parsed from your REST API -->
</OutputClaims>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>
My orchestration step.
<OrchestrationStep Order="7" Type="ClaimsExchange">
<Preconditions>
<Precondition Type="ClaimsExist" ExecuteActionsIf="false">
<Value>extension_empOPRID</Value>
<Action>SkipThisOrchestrationStep</Action>
</Precondition>
</Preconditions>
<ClaimsExchanges>
<ClaimsExchange Id="REST-CheckInactiveEmployee" TechnicalProfileReferenceId="REST-CheckInactiveEmployee" />
</ClaimsExchanges>
</OrchestrationStep>
Upvotes: 0
Views: 999
Reputation: 108
REST API calls that are their own orchestration steps return an exception to the redirect URL when the call returns an HTTP error code (as you saw).
However, you can add validation profiles to generally any self-asserted profile, so you can add your REST API call as a ValidationTechnicalProfile
to the self-asserted profile associated with the sign-in option.
For example, in the MS ADB2C custom policy starterpack's combined sign-in and sign-up journey, the first orchestration step is defined like below:
<OrchestrationStep Order="1" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin">
<ClaimsProviderSelections>
<ClaimsProviderSelection TargetClaimsExchangeId="FacebookExchange" />
<ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninEmailExchange" />
</ClaimsProviderSelections>
<ClaimsExchanges>
<ClaimsExchange Id="LocalAccountSigninEmailExchange" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Email" />
</ClaimsExchanges>
</OrchestrationStep>
You can see the technical profile ID used for handling the sign-in fields is SelfAsserted-LocalAccountSignin-Email
. If you check this profile in the same policy, it is a self-asserted profile, and the normal username/password check on login is implemented as a ValidationTechnicalProfile
on it. Assuming you were creating a policy based on the starterpack, you could add your API call profile as another ValidationTechnicalProfile
on the SelfAsserted-LocalAccountSignin-Email
self-asserted profile, and your profile would also be validated when the user attempts to sign in using the form on the sign in page. e.g.:
<ValidationTechnicalProfiles>
<ValidationTechnicalProfile ReferenceId="login-NonInteractive" />
<ValidationTechnicalProfile ReferenceId="REST-CheckInactiveEmployee" />
</ValidationTechnicalProfiles>
(the order of the profiles is the order they will be called in, so you should order them based on whether you want the username/password validity or your API call to be validated first).
Additionally, for B2C to display an error message of your choice (when used for validation on any self-asserted profile, not just one used for a sign-in page), your REST API will need to return an appropriate response - a 4xx
HTTP response (such as a 409
error) with a JSON object containing the following fields:
{
"version": "1.0.0",
"status": 409,
"userMessage": "An error occurred in validation."
}
Where version
contains a version number for your API in string format (it can be whatever version number you consider appropriate), status
contains your HTTP status code as an integer (documentation says it has to be 409 specifically, but I'm not whether this is actually the case or it should match the response's status code), and userMessage
contains the message you want B2C to display on the form in response to the error.
Upvotes: 0