Localizing the API response in Custom Police Azure ADB2C - azure-ad-b2c

I have implemented localization in Azure ADB2C custom policy.
<ClaimType Id="signInName">
<DisplayName>Please enter your email</DisplayName>
<DataType>string</DataType>
<UserHelpText>Enter your email address to signin</UserHelpText>
<Restriction>
<Pattern RegularExpression="^[a-zA-Z0-9_.+-]+#[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$"/>
</Restriction>
</ClaimType>
<Localization Enabled="true">
<SupportedLanguages DefaultLanguage="en" MergeBehavior="ReplaceAll">
<SupportedLanguage>en</SupportedLanguage>
<SupportedLanguage>es</SupportedLanguage>
</SupportedLanguages>
<LocalizedResources Id="en">
<LocalizedStrings>
<LocalizedString ElementType="ClaimType" ElementId="signInName" StringId="DisplayName">Please enter your email</LocalizedString>
<LocalizedString ElementType="ClaimType" ElementId="signInName" StringId="UserHelpText">Enter your email address to signin</LocalizedString>
</LocalizedStrings>
</LocalizedResources>
<LocalizedResources Id="es">
<LocalizedStrings>
<LocalizedString ElementType="ClaimType" ElementId="signInName" StringId="DisplayName">Por favor introduzca su correo electrónico</LocalizedString>
<LocalizedString ElementType="ClaimType" ElementId="signInName" StringId="UserHelpText">Ingrese su dirección de correo electrónico para iniciar sesión</LocalizedString>
</LocalizedStrings>
</LocalizedResources>
</Localization>
Everything is working as expected but when the login button is clicked, an API call is made and the response is always in English. Also the query string parameter to indicate the language is not sent in the API call. Any help is greatly appreciated.

You need to first find what is the string ID which is showing this error.
We support these IDs for localization which you might have customized in your policies.
Then, once you know which ID is being used for your error message, you can add a LocalizedString element like below (For example, I am assuming the ElementType is ErrorMessage and StringID is DefaultMessage):
<LocalizedString ElementType="ErrorMessage" StringId="DefaultMessage">#Invalid username or password.</LocalizedString>
You can find out different examples of the same here: https://learn.microsoft.com/en-us/azure/active-directory-b2c/custom-policy-localization

Related

Localization of custom claim in Azure AD B2C custom policy

I have the following claim type in my relying party building block section:
<ClaimType Id="extension_mfaByPhoneOrEmail">
<DisplayName>Please select your preferred MFA method</DisplayName>
<DataType>string</DataType>
<UserInputType>RadioSingleSelect</UserInputType>
<Restriction>
<Enumeration Text="Phone" Value="phone" SelectByDefault="true" />
<!-- <Enumeration Text="Email " Value="email" SelectByDefault="false" /> -->
</Restriction>
</ClaimType>
I'm not able to add the localization for another language, I have already set the trustframeworklocalization.xml file and it'w works for the other parts of the code.
problem solved in part, I added on the selfasserted content definition id the following rows:
<!-- Self Asserted localized strings (English) -->
<LocalizedResources Id="api.selfasserted.en">
<LocalizedStrings>
<LocalizedString ElementType="ClaimType" ElementId="extension_mfaByPhoneOrEmail" StringId="DisplayName">Please select your preferred MFA method</LocalizedString>
</LocalizedStrings>
</LocalizedResources>
problem solved, i added on the selfasserted content definition id the following rows:
<LocalizedResources Id="api.selfasserted.en">
<LocalizedCollections>
<LocalizedCollection ElementType="ClaimType" ElementId="extension_mfaByPhoneOrEmail" TargetCollection="Restriction">
<Item Text="Phone" Value="phone" />
<Item Text="Email" Value="email" />
</LocalizedCollection>
</LocalizedCollections>
<LocalizedStrings>
<LocalizedString ElementType="ClaimType" ElementId="extension_mfaByPhoneOrEmail" StringId="DisplayName">Please select your preferred MFA method</LocalizedString>
</LocalizedStrings>
</LocalizedResources>

How to dynamically display data in B2C sign up page with a localized String?

So I am trying to display a query parameter in my HTML page. I have not had an issue doing this is a claim, I created this.
<ClaimsSchema>
<ClaimType Id="ID">
<DisplayName>ID</DisplayName>
<DataType>string</DataType>
</ClaimType>
</ClaimsSchema>
Then in my relaying party I have this,
<OutputClaim ClaimTypeReferenceId="ID" AlwaysUseDefaultValue="true" DefaultValue="{OAUTH-KV:ID}" />
and in the sign in URL we have &ID=12345
What we are trying to do is send out sign up links with a specific ID value. Then when they make it to the sign in / sign up page the join now link has that ID appended to it.
So like www.mycompany.com/register/id=12345
I have localized the strings in self asserted page.
<Localization>
<LocalizedResources Id="api.selfasserted">
<LocalizedStrings>
<LocalizedString ElementType="UxElement" StringId="disclaimer_msg_intro">Dont have an account?</LocalizedString>
<LocalizedString ElementType="UxElement" StringId="disclaimer_link_1_text">Join Now</LocalizedString>
<LocalizedString ElementType="UxElement" StringId="disclaimer_link_1_url">http://www.mycompany.com/register/id=</LocalizedString>
</LocalizedStrings>
</LocalizedResources>
</Localization>
Is there a way to inject that claim in that link?
I know i can do this with JS... i am trying to avoid using Javascript.
It’s not possible to do dynamic claim resolving in localised elements function. You’re going to have to use JS.

Azure AD B2C Signup Page Customization

Currently Implementing a b2c signup flow via custom policies. Working on a usecase for b2c user registration page, when a user left the “required fields” as empty then the following error message is displayed as “This information is required” by default.
But how to customize to these mandatory field error message as “Name is required” or “Phone number is required” or “Telephone number is required”?
I haven’t found a right localization string ID to handle these mandatory field error message, Instead of a generic default error message. Any helpful suggestions?
I think you have to use localization to overwrite messages and texts.
<LocalizedResources Id="api.signuporsignin.en">
<LocalizedStrings>
<LocalizedString ElementType="ClaimType" ElementId="email" StringId="DisplayName">Email Address</LocalizedString>
<LocalizedString ElementType="UxElement" StringId="heading">Sign in</LocalizedString>
<LocalizedString ElementType="UxElement" StringId="social_intro">Sign in with your social account</LocalizedString>
<LocalizedString ElementType="UxElement" StringId="local_intro_generic">Sign in with your {0}</LocalizedString>
<LocalizedString ElementType="UxElement" StringId="requiredField_password">Please enter your password</LocalizedString>
<LocalizedString ElementType="UxElement" StringId="requiredField_generic">Please enter your {0}</LocalizedString>
<LocalizedString ElementType="UxElement" StringId="invalid_generic">Please enter a valid {0}</LocalizedString>
<LocalizedString ElementType="UxElement" StringId="createaccount_one_link">Sign up now</LocalizedString>
<LocalizedString ElementType="UxElement" StringId="createaccount_two_links">Sign up with {0} or {1}</LocalizedString>
<LocalizedString ElementType="UxElement" StringId="createaccount_three_links">Sign up with {0}, {1}, or {2}</LocalizedString>
<LocalizedString ElementType="UxElement" StringId="forgotpassword_link">Forgot your password?</LocalizedString>
<LocalizedString ElementType="UxElement" StringId="button_signin">Sign in</LocalizedString>
<LocalizedString ElementType="UxElement" StringId="divider_title">OR</LocalizedString>
<LocalizedString ElementType="UxElement" StringId="unknown_error">We are having trouble signing you in. Please try again later.</LocalizedString>
<!-- Uncomment the remember_me only if the keep me signed in is activated.
<LocalizedString ElementType="UxElement" StringId="remember_me">Keep me signed in</LocalizedString> -->
<LocalizedString ElementType="ClaimsProvider" StringId="FacebookExchange">Facebook</LocalizedString>
<LocalizedString ElementType="ErrorMessage" StringId="UserMessageIfInvalidPassword">Your password is incorrect.</LocalizedString>
<LocalizedString ElementType="ErrorMessage" StringId="UserMessageIfPasswordExpired">Your password has expired.</LocalizedString>
<LocalizedString ElementType="ErrorMessage" StringId="UserMessageIfClaimsPrincipalDoesNotExist">We can't seem to find your account.</LocalizedString>
<LocalizedString ElementType="ErrorMessage" StringId="UserMessageIfOldPasswordUsed">Looks like you used an old password.</LocalizedString>
<LocalizedString ElementType="ErrorMessage" StringId="DefaultMessage">Invalid username or password.</LocalizedString>
<LocalizedString ElementType="ErrorMessage" StringId="UserMessageIfUserAccountDisabled">Your account has been locked. Contact your support person to unlock it, then try again.</LocalizedString>
<LocalizedString ElementType="ErrorMessage" StringId="UserMessageIfUserAccountLocked">Your account is temporarily locked to prevent unauthorized use. Try again later.</LocalizedString>
<LocalizedString ElementType="ErrorMessage" StringId="AADRequestsThrottled">There are too many requests at this moment. Please wait for some time and try again.</LocalizedString>
</LocalizedStrings>
</LocalizedResources>
The specific string ID will vary depending on the claim. Use Customize Language guidance via XML policy to edit Localization element for the localized string.
See page layout version for your specific ID (if you require a version update).
I noticed in the example you posted, you had "UserMessageIfMissingRequiredElemnt" rather than "UserMessageIfMissingRequiredElement" (yours is missing that final "e"), this is perhaps why the localization didn't work

Remove text from B2C custom policy sign up flow

In the sign up page, when the existing user tries to sign up, it gives an error, this user already exists. But it shows the text, ''confirmed email address'' , how can we remove the text?
when you create custom policy you should be able to define this message in Localization part of the policy.
Example of this file is here:
https://github.com/Azure-Samples/active-directory-b2c-custom-policy-starterpack/blob/main/Display%20Controls%20Starterpack/LocalAccounts/TrustFrameworkLocalization.xml
<!-- Generic errors -->
<LocalizedString ElementType="ErrorMessage" StringId="ServiceThrottled">There are too many requests at this moment. Please wait for some time and try again.</LocalizedString>
<LocalizedString ElementType="ErrorMessage" StringId="UserMessageIfClaimNotVerified">Claim not verified: {0}</LocalizedString>
<LocalizedString ElementType="ErrorMessage" StringId="UserMessageIfClaimsPrincipalAlreadyExists">A user with the specified ID already exists. Please choose a different one.</LocalizedString>
<LocalizedString ElementType="ErrorMessage" StringId="UserMessageIfIncorrectPattern">Incorrect pattern for: {0}</LocalizedString>
<LocalizedString ElementType="ErrorMessage" StringId="UserMessageIfInvalidInput">{0} has invalid input.</LocalizedString>
<LocalizedString ElementType="ErrorMessage" StringId="UserMessageIfMissingRequiredElement">Missing required element: {0}</LocalizedString>
<LocalizedString ElementType="ErrorMessage" StringId="UserMessageIfValidationError">Error in validation by: {0}</LocalizedString>

Localization of TOTP MFA controls

I've implemented TOTP based MFA as described in the documentation (https://learn.microsoft.com/en-us/azure/active-directory-b2c/display-control-time-based-one-time-password) and samples (https://github.com/azure-ad-b2c/samples/tree/master/policies/totp).
Now I would like to translate texts displayed during MFA enrollment and verification. However, I couldn't find anything in documentation regarding StringIds which can be overridden using B2C localization mechanism.
There is a similar question on GitHub - https://github.com/azure-ad-b2c/samples/issues/378, without response since 10 days.
I would like to translate following screens:
If you want to translate the screens as shown above, you can do the following:
In your TrustFrameworkBase.xml, under the node ContentDefinitions, add the following
<ContentDefinition Id="api.selfasserted.totp">
<LoadUri>~/tenant/templates/AzureBlue/selfAsserted.cshtml</LoadUri>
<RecoveryUri>~/common/default_page_error.html</RecoveryUri>
<DataUri>urn:com:microsoft:aad:b2c:elements:contract:selfasserted:2.1.9</DataUri>
<Metadata>
<Item Key="DisplayName">Collect information from user page</Item>
</Metadata>
</ContentDefinition>
In your TrustFrameworkLocalization.xml ContentDefinitions node add
<ContentDefinition Id="api.selfasserted.totp">
<LocalizedResourcesReferences MergeBehavior="Prepend">
<LocalizedResourcesReference Language="en" LocalizedResourcesReferenceId="api.selfasserted.totp.en" />
<LocalizedResourcesReference Language="af" LocalizedResourcesReferenceId="api.selfasserted.totp.af" />
<!-- Add more languages here -->
</LocalizedResourcesReferences>
</ContentDefinition>
Finally, also in the localization xml, you can add the following translations (Change the .af to your language preference of course)
<!-- Edit profile page English-->
<LocalizedResources Id="api.selfasserted.totp.en">
<LocalizedStrings>
<LocalizedString ElementType="ClaimType" ElementId="totpQrCodeControl" StringId="DisplayName">You can download the Microsoft Authenticator app or use any other authenticator app of your choice.</LocalizedString>
<LocalizedString ElementType="DisplayControl" ElementId="totpQrCodeControl" StringId="title_text">Scan the QR code</LocalizedString>
<LocalizedString ElementType="DisplayControl" ElementId="totpQrCodeControl" StringId="info_msg">Using your app scan this QR code and click "Continue"</LocalizedString>
<LocalizedString ElementType="DisplayControl" ElementId="totpQrCodeControl" StringId="link_text">Can't scan? Try this</LocalizedString>
<LocalizedString ElementType="ClaimType" ElementId="otpCode" StringId="UserHelpText">Enter the 6-digit verification code generated by the the Authenticator app in the box.</LocalizedString>
<LocalizedString ElementType="ClaimType" ElementId="otpCode" StringId="DisplayName">Enter your code</LocalizedString>
<LocalizedString ElementType="ClaimType" ElementId="QrCodeVerifyInstruction" StringId="DisplayName">Enter the verification code from your authenticator app​.</LocalizedString>
<LocalizedString ElementType="ClaimType" ElementId="QrCodeScanInstruction" StringId="DisplayName">Once you've downloaded the Authenticator app, you can use any of the methods below to continue with enrollment.</LocalizedString>
<LocalizedString ElementType="DisplayControl" ElementId="authenticatorAppIconControl" StringId="title_text">Download the Microsoft Authenticator using the download links for iOS and Android or use any other authenticator app of your choice.</LocalizedString>
<LocalizedString ElementType="DisplayControl" ElementId="authenticatorInfoControl" StringId="title_text">Enter the account details manually</LocalizedString>
<LocalizedString ElementType="DisplayControl" ElementId="authenticatorInfoControl" StringId="account_name">Account Name:</LocalizedString>
<LocalizedString ElementType="DisplayControl" ElementId="authenticatorInfoControl" StringId="display_prefix">Secret</LocalizedString>
<LocalizedString ElementType="DisplayControl" ElementId="authenticatorInfoControl" StringId="collapse_text">Still having trouble?</LocalizedString>
<LocalizedString ElementType="UxElement" StringId="button_continue">Continue</LocalizedString>
<LocalizedString ElementType="UxElement" StringId="button_cancel">Cancel</LocalizedString>
</LocalizedStrings>
</LocalizedResources>
<LocalizedResources Id="api.selfasserted.totp.af">
<LocalizedStrings>
<LocalizedString ElementType="ClaimType" ElementId="totpQrCodeControl" StringId="DisplayName">Jy kan die Microsoft Authenticator-toepassing aflaai of enige ander Authenticator-toepassing van jou keuse gebruik.</LocalizedString>
<LocalizedString ElementType="DisplayControl" ElementId="totpQrCodeControl" StringId="title_text">Skandeer die QR-kode</LocalizedString>
<LocalizedString ElementType="DisplayControl" ElementId="totpQrCodeControl" StringId="link_text">Kan jy nie skandeer nie? Probeer hierdie</LocalizedString>
<LocalizedString ElementType="DisplayControl" ElementId="totpQrCodeControl" StringId="info_msg">Deur jou toepassing te gebruik, skandeer hierdie QR-kode en klik "Gaan voort"</LocalizedString>
<LocalizedString ElementType="ClaimType" ElementId="otpCode" StringId="UserHelpText">Voer die 6-syfer-verifikasiekode in wat deur die die Authenticator-toepassing gegenereer is in die blokkie.</LocalizedString>
<LocalizedString ElementType="ClaimType" ElementId="otpCode" StringId="DisplayName">Sleutel in jou kode</LocalizedString>
<LocalizedString ElementType="ClaimType" ElementId="QrCodeVerifyInstruction" StringId="DisplayName">Voer die verifikasiekode vanaf jou verifikasie-toepassing in.</LocalizedString>
<LocalizedString ElementType="ClaimType" ElementId="QrCodeScanInstruction" StringId="DisplayName">Sodra jy die Authenticator-toepassing afgelaai het, kan jy enige van die metodes hieronder gebruik om voort te gaan met inskrywing.</LocalizedString>
<LocalizedString ElementType="DisplayControl" ElementId="authenticatorAppIconControl" StringId="title_text">Laai die Microsoft Authenticator af deur die aflaaiskakels vir iOS en Android te gebruik of gebruik enige ander Authenticator-toepassing van jou keuse.</LocalizedString>
<LocalizedString ElementType="DisplayControl" ElementId="authenticatorInfoControl" StringId="title_text">Voer die rekeningbesonderhede handmatig in</LocalizedString>
<LocalizedString ElementType="DisplayControl" ElementId="authenticatorInfoControl" StringId="account_name">Rekeningnaam:</LocalizedString>
<LocalizedString ElementType="DisplayControl" ElementId="authenticatorInfoControl" StringId="display_prefix">Geheim</LocalizedString>
<LocalizedString ElementType="DisplayControl" ElementId="authenticatorInfoControl" StringId="collapse_text">Het u steeds probleme?</LocalizedString>
<LocalizedString ElementType="UxElement" StringId="button_continue">Gaan voort</LocalizedString>
<LocalizedString ElementType="UxElement" StringId="button_cancel">Kanselleer</LocalizedString>
</LocalizedStrings>
</LocalizedResources>
This should give you the following output then
NOTE Some of the error message you will have to test and also figure out how to translate, the codes for these can be found here, but I did find one or 2 that does not work as I expect, and still trying to get it all to translate proper. Wish there was better documentation on this

Resources