ContentDefinitionParameters with Default Value - azure-ad-b2c

I know how to send extra information during signin.
<ContentDefinitionParameters>
<Parameter Name="campaignId">{OAUTH-KV:customUi}</Parameter>
</ContentDefinitionParameters>
The only place I will be using this value is in the Content Definitions like below
<ContentDefinition Id="api.signuporsignin">
<LoadUri>cdn.mydomain.com/{OAUTH-KV:ui-version}/thepage.html</LoadUri>
<RecoveryUri>~/common/default_page_error.html</RecoveryUri>
<DataUri>urn:com:microsoft:aad:b2c:elements:contract:unifiedssp:1.2.0</DataUri>
<Metadata>
<Item Key="DisplayName">Signin and Signup</Item>
</Metadata>
<LocalizedResourcesReferences MergeBehavior="Prepend">
<LocalizedResourcesReference Language="en" LocalizedResourcesReferenceId="api.signuporsignin.en" />
</LocalizedResourcesReferences>
</ContentDefinition>
The problem with this is that if the front end, does not add the ui-version to the query string the login will error. I was wondering if it was possible to give this a default value? That way, if the parameter is missing, I can default it and the login will work.
Anyone any ideas on how best to achieve this?

If you want to append a static query parameter using custom policy use input claims
</CryptographicKeys>
<InputClaims>
<InputClaim ClaimTypeReferenceId="myQueryParam" DefaultValue="staticParamValue"/>
</InputClaims>
<OutputClaims>
this will append as &myQueryParam=staticParamValue.
If the input claim is not using a defaultValue, it will send whatever value is inside the claim at this point in time of policy execution. It could be a claims resolver too.

Related

Azure AD B2C - call rest api with parameter in header

I'm trying to call a rest api in a technical profile which requires parameters to be passed to it through the header, but I'm unable to do so. I have:
<TechnicalProfile Id="techProfile1">
<DisplayName>Technical Profile 1</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://xxxxxxx.azurewebsites.net/api/controller/action</Item>
<Item Key="AuthenticationType">Basic</Item>
<Item Key="SendClaimsIn">Header</Item>
<Item Key="AllowInsecureAuthInProduction">true</Item>
</Metadata>
<CryptographicKeys>
<Key Id="BasicAuthenticationUsername" StorageReferenceId="xxxxxx" />
<Key Id="BasicAuthenticationPassword" StorageReferenceId="xxxxxx" />
</CryptographicKeys>
<InputClaims>
<InputClaim ClaimTypeReferenceId="claimName1" PartnerClaimType="paramName1" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="output1"/>
</OutputClaims>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
</TechnicalProfile>
Where the value I'm trying to pass in is the ClaimName1 claim, and the parameter name is paramName1. Am I correct in using the InputClaim section for this?
The response back that I get is: AADB2C90075: The claims exchange 'techProfile1' specified in step '3' returned HTTP error response with Code 'InternalServerError' and Reason 'Internal Server Error'.
Am I right in assuming that the parameter is not being passed to the api? When I change the ServiceUrl to: https://xxxxxxx.azurewebsites.net/api/controller/action?paramName1=yyyy (where yyyy is the value held in the claimName1 claim), then it works as expected.
<Item Key="SendClaimsIn">Header</Item>
instead of the above one try the below one
<Item Key="SendClaimsIn">QueryString</Item>
This will add the input claim as query param.

Custom policy showing error labels on page load

I saw a question similar here. I'm facing the same issue with my policy too.
<ContentDefinition Id="api.localaccountsignup">
<LoadUri>https://mysite.azurewebsites.net/b2c/signup</LoadUri>
<RecoveryUri>~/common/default_page_error.html</RecoveryUri>
<DataUri>urn:com:microsoft:aad:b2c:elements:selfasserted:1.1.0</DataUri>
<Metadata>
<Item Key="DisplayName">Local account sign up page</Item>
</Metadata>
<LocalizedResourcesReferences MergeBehavior="Prepend">
<LocalizedResourcesReference Language="en" LocalizedResourcesReferenceId="signup_en" />
</LocalizedResourcesReferences>
</ContentDefinition>
Validation errors are showing on the page load itself. As the solution of the question says hide that using CSS, but is there any other solution to fix this from B2C without using style.?

B2C: Localization for messages originating from REST API

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.

In the PhoneFactor-InputOrVerify Technical Profile (B2C custom user flow), is it possible to allow the user to change their default mobile number?

In Azure B2C custom policies, our business process requirements mean we need control over whether:
The user may not replace the mobile number we have on record for them (i.e. first-time password set experience), or
We present the number we hold on record for them by default, but allow the user to overtype and save this number with a new number (e.g. logged-in edit profile experience).
The question: Is there a way I can allow the user to replace the number we hold on record for them with a new number, perhaps by the addition of a new button [Provide New Number] in this series:
[Send Code] [Call Me] [New Button To Provide New Number] [Cancel]
PhoneFactor-InputOrVerify sample screen (image)
The code below is a slight modification of the similarly-named policy from the B2C Custom Policy Starterpack.
Note how in this example we're providing the mobile phone number value stored in the mobile property of the user object as strongAuthenticationNumber. This is because there is currently no way of setting the MFA number programmatically. (Thanks for your help, Chris Padgett.)
Other than this, the policy is as per starterpack.
<ClaimsProvider>
<DisplayName>PhoneFactor</DisplayName>
<TechnicalProfiles>
<TechnicalProfile Id="PhoneFactor-InputOrVerify">
<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" />
<!--InputClaim ClaimTypeReferenceId="strongAuthenticationPhoneNumber" /-->
<InputClaim ClaimTypeReferenceId="mobile" PartnerClaimType="strongAuthenticationPhoneNumber" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="Verified.strongAuthenticationPhoneNumber" PartnerClaimType="Verified.OfficePhone" />
<OutputClaim ClaimTypeReferenceId="newPhoneNumberEntered" PartnerClaimType="newPhoneNumberEntered" />
</OutputClaims>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-MFA" />
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>
I suspect there may be some metadata setting to enable a button or text input box as described, but to my knowledge there is no documentation for this yet.
You must create a custom flow for this that:
Prompts the end user to sign in with a local or external account.
Reads the current phone number for the end user from Azure AD.
Prompts the end user to verify their current phone number.
Prompts the end user to enter and verify their new phone number.
Writes the new phone number for the end user to Azure AD.
See this sample policy.

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