B2C: Localization for messages originating from REST API - azure

I am currently implementing this example to use an rest API during the user registration.
The basic idea is that the API throws an 409 Conflict error to interrupt the registration.
// Can I return a special "StringId" or something here for localization?
return new ConflictObjectResult(new B2CResponseModel($"A verification email sent to you. Please open your mail box and click on the link. If you didn't receive the email, please click on the 'Send verification email' button.", HttpStatusCode.Conflict));
I want to show the user a message that is localized to their current language. I would prefer to do the localization within the custom policies, but I would also accept a solution within the API (would need to get the User Language for this).
Is there a way to do this localization? Like returning a StringId via API and using this within the policy?
I am also considering not returning an error from the API, to show the message in a new screen instead (like How to display error returned from custom REST API endpoint in a subsequent orchestration step?). However, localization options for this elude me as well.

In case anybody is looking for a way to send the user's locale to the REST API:
https://learn.microsoft.com/nb-no/azure/active-directory-b2c/claim-resolver-overview
<TechnicalProfile Id="REST-API-SendVerificationEmail">
<DisplayName>Sign-Up send link</DisplayName>
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<Metadata>
<Item Key="ServiceUrl">https://xxxx</Item>
<Item Key="AuthenticationType">None</Item>
<Item Key="SendClaimsIn">Body</Item>
</Metadata>
<InputClaims>
<InputClaim ClaimTypeReferenceId="email" />
<InputClaim ClaimTypeReferenceId="userLanguage" DefaultValue="{Culture:LanguageName}" />
<InputClaim ClaimTypeReferenceId="policyId" PartnerClaimType="policy" DefaultValue="{Policy:PolicyId}" />
<InputClaim ClaimTypeReferenceId="scope" DefaultValue="{OIDC:scope}" />
<InputClaim ClaimTypeReferenceId="clientId" DefaultValue="{OIDC:ClientId}" />
</InputClaims>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
</TechnicalProfile>

Hope this is similar to this
See the answer by Jas Suri. Pass the localisation parameter to API and return the localised message or can return an error code and based on that display translated message using policy itself.

Related

How to customize the error page for REST API Failures in Azure AD B2C custom policy?

Customizing the error page for REST API Failures which we are calling in the Orchestration Steps :
We have a scenario where we need to call the Rest API before any Self asserted Page being presented to the user
<OrchestrationStep Order="5" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="Rest-API-Call" TechnicalProfileReferenceId="Some-Rest API " />
</ClaimsExchanges>
</OrchestrationStep>
<TechnicalProfile Id="Some-Rest API">
<DisplayName>REST call</DisplayName>
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<Metadata>
<Item Key="ServiceUrl"> https://{url}</Item>
<Item Key="AuthenticationType">Bearer</Item>
<Item Key="SendClaimsIn">Url</Item>
<Item Key="UseClaimAsBearerToken">token</Item>
<Item Key="IncludeClaimResolvingInClaimsHandling">true</Item>
<Item Key="AllowInsecureAuthInProduction">false</Item>
<Item Key="DefaultUserMessageIfRequestFailed">Unable to Process your Request</Item>
</Metadata>
<InputClaims>
<InputClaim ClaimTypeReferenceId="token" />
<InputClaim ClaimTypeReferenceId="objectId" />
</InputClaims>
</TechnicalProfile>
Whenever this API Fails with status code 4xx and 5xx, we will be getting the default error message which Microsoft is providing
Sorry, We are having trouble signing you in. We track these errors automatically , but if the problem persists feel free to contact us. In the meantime, please try again...
We are getting this Page, Could you please help us is there any way we can customize this error Page, with some default exception html Page
where we can show our customized page instead of this default page.
The default API error page is defined in the content definition api.error if you started from one of the custom policy starter packs. You can modify that content definition to point to your own HTML page so you can customize the styling. Here's a link to that doc: https://learn.microsoft.com/en-us/azure/active-directory-b2c/customize-ui-with-html?pivots=b2c-custom-policy
api.error however only displays on unhandled exceptions which might not cover your use case.
An answer to another post (Error handling in Azure B2C Custom Policy REST Call) from someone on the engineering team states that anything but a 200 from an API halts the journey execution and returns an error to the app immediately, so unless you put the rest call in a validation tech profile, this is the behavior you're going to get.

Is there a way to display data returned from an API REST response in Azure AD B2C?

I'm working on a password reset flow and I need to display a custom message returned by an API response, but I can't find a way to display this message. I've tried the following.
<ClaimType Id="userMessage">
<DisplayName>userMessage</DisplayName>
<DataType>string</DataType>
<UserInputType>Paragraph</UserInputType>
</ClaimType>
<TechnicalProfile Id="SendOtp">
<DisplayName>Send Otp</DisplayName>
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<Metadata>
<Item Key="ServiceUrl">SomeUrl</Item>
<Item Key="AuthenticationType">ApiKeyHeader</Item>
<Item Key="SendClaimsIn">Body</Item>
</Metadata>
<InputClaims>
<InputClaim ClaimTypeReferenceId="email" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="userMessage" />
</OutputClaims>
</TechnicalProfile>
But it doesn't show anything.
Have your API return a HTTP 409 error response code. The flow will not continue after this point, until your API responds with HTTP 200 upon the user submitting the page again.
https://learn.microsoft.com/en-us/azure/active-directory-b2c/restful-technical-profile#error-handling
You cannot display a message from the API, unless the API responds with HTTP 409 error status code.
If you want to display a message on success, then localise the message for the display control for send code:
https://learn.microsoft.com/en-us/azure/active-directory-b2c/localization-string-ids#verification-display-control-user-interface-elements

Email verification box disappears when passing email from Facebook as input claim to self-asserted profile

We want to force users to provide and verify their email address even when they reject passing their email claim from Facebook.
We created an orchestration step which calls the following technical profile after coming back from Facebook:
<TechnicalProfile Id="SelfAsserted-ConfirmEmailSocial">
<DisplayName>Confirm email social</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</Item>
</Metadata>
<InputClaims>
<InputClaim ClaimTypeReferenceId="email" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="Verified.Email" Required="true" />
</OutputClaims>
</TechnicalProfile>
If the user rejects the facebook setting, the code works as expected: The verification control is shown.
However, if the user accepts the facebook setting, both the input field and the verification control disappear. (And the email gets pre-populated)
(Someone explains here stack overflow that the control is too dumb to realize that you want to verify the input claim https://stackoverflow.com/a/44429492/509464) but we haven't been able to get the suggested solution to work.
How can we force validation of emails provided in a previous orchestration step?
Update:
It seems we could create a workaround by making the input claim read-only somehow. (But only if it was empty).
Yes the only option is making it read only, since otherwise we assume the passed in email is already verified, which it is with Facebook. If you change the email, then you must verify it. You could modify the JavaScript/css to show the controls. Or in the custom policy, use an input claim transform to copy the email claim into a new read-only claim id. Then pre-populate the form using input claim. Then display the claim using output claim.

Invoke Rest API on email verification ADB2C custom policy

The default functionality of ADB2C for email verification verifies the verification code sent to the corresponding email.
However it does not check whether that email is already registered or not. Until now we have been doing this by calling a Rest API on clicking create. But now it is required to check if that email is already registered or not at the email verification step.
Is there a way to call a Rest API at email verification step? If yes, then how can it be done?
You could separate the input of email address and user data to a different page, and then just do the email verification on a next page. That way you can check if the user exists on the previous page and verify the email on the next.
You also do not need to call out to a REST endpoint to check if they exist. You can use a technical profile that inherits the AAD-Common Technical profile to see if they exist.
<TechnicalProfile Id="DoesUserExist">
<Metadata>
<Item Key="Operation">Read</Item>
<Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">false</Item>
</Metadata>
<InputClaims>
<InputClaim ClaimTypeReferenceId="email" Required="true" PartnerClaimType="signInNames" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="UserSearchOID" PartnerClaimType="objectId" />
</OutputClaims>
<IncludeTechnicalProfile ReferenceId="AAD-Common" />
</TechnicalProfile>

ad b2c allow user to change MFA setting

how would I allow the user to change their MFA setting like their phone number? I don't see any option for them to be able to do that easily.
Try this. B2C MFA reset was the reason I wrote it.
http://gordon.byers.me/azure/resetting-a-users-azure-ad-multi-factor-mfa-requirement/
As it's powershell you could put it inside an Azure function and call it via HTTP to allow the user to self serve.
Currently it is not possible to change an Azure AD B2C users' MFA settings.
There's already an ask for this ask in the Azure AD B2C forum that you should vote for:
https://feedback.azure.com/forums/169401-azure-active-directory/suggestions/15334329-change-security-info
The MFA phone number can be changed with custom policies. When you create a UserJourney that invokes a TechnicalProfile that does not take the strongAuthenticationPhoneNumber as InputClaim, IEF acts as if the user registers for MFA for the first time.
Of course you need to think about security measures, since it is a second factor that the user changes (e.g. ask the user to input some data, that can be validated, before allowing the user to change the phonenumber). Otherwise the use of MFA makes no sense.
Apparently, user's can't do that as stated by Saca 😢
Admins 👮 can do this on the user's behalf via the Azure Portal though:
Users -> All users -> Pick the user you're interested in -> Update Phone under Authentication contact info
Looks like this is now possible with custom policies.
There is a full example here: https://github.com/azure-ad-b2c/samples/tree/master/policies/edit-mfa-phone-number
In case the link breaks, the key part appears to be this:
<TechnicalProfiles>
<TechnicalProfile Id="PhoneFactor-EditAndVerify">
<DisplayName>PhoneFactor</DisplayName>
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.PhoneFactorProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<Metadata>
<Item Key="ContentDefinitionReferenceId">api.phonefactor</Item>
<Item Key="ManualPhoneNumberEntryAllowed">true</Item>
</Metadata>
<CryptographicKeys>
<Key Id="issuer_secret" StorageReferenceId="B2C_1A_TokenSigningKeyContainer" />
</CryptographicKeys>
<InputClaimsTransformations>
<InputClaimsTransformation ReferenceId="CreateUserIdForMFA" />
</InputClaimsTransformations>
<InputClaims>
<InputClaim ClaimTypeReferenceId="userIdForMFA" PartnerClaimType="UserId" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="Verified.strongAuthenticationPhoneNumber" PartnerClaimType="Verified.OfficePhone" />
<OutputClaim ClaimTypeReferenceId="newPhoneNumberEntered" PartnerClaimType="newPhoneNumberEntered" />
</OutputClaims>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
</TechnicalProfile>

Resources