Azure B2C custom policy passwordless signin schema validation error - azure

I am using Azure B2C custom policy for passwordless signin following this sample.
The <BuildingBlocks> section has the <ClaimsTransformations>.....</ClaimsTransformations> which defines random password generation. To customize the UI for my login screens I have also added <ContentDefinitions> .... </ContentDefinitions> inside <BuildingBlocks> section.
Now I am getting a validation error when trying to upload the TrustFrameworkExtensions_passwordless_only.xml file saying that the ---> element <BuildingBlocks> has invalid child element <ClaimsTransformations>. List of possible elements expected: Localisation, DisplayControls.
This is strange because in the reference schema ClaimsTransformations is also a valid element. Not idea why I am getting this error. Can anyone please help me with this issue?

According to official AD B2C custom policy documentation on BuildingBlocks:
The BuildingBlocks element contains the following elements that must be specified in the order defined:
<BuildingBlocks>
<ClaimsSchema>
...
</ClaimsSchema>
<Predicates>
...
</Predicates>
<PredicateValidations>
...
</PredicateValidations>
<ClaimsTransformations>
...
</ClaimsTransformations>
<ContentDefinitions>
...
</ContentDefinitions>
<Localization>
...
</Localization>
<DisplayControls>
...
</DisplayControls>
</BuildingBlocks>
So the order matters and you need to place ContentDefinitions block after ClaimsTransformations block.

Related

What is the data type?

I am using ADB2C's custom policies to create the screens.
What are the variable names and data types for user IDs and passwords in login and MFA?
Also, what are the variable names and data types for the phone number and confirmation code in MFA?
I don't know because it is not the source I described.
• According to the official Microsoft documentation, the username in Azure AD B2C custom policy is denoted by a variable attribute of ‘signInNames.userName’ and its datatype is ‘String’. Similarly, for password, the variable attribute assigned is ‘password’ and its datatype is ‘String’. For the phone number, the assigned attribute is ‘mobile’ or ‘mobilePhone’ and the datatype is ‘String’ but if you want to use that phone number for MFA in Azure AD B2C, the variable attribute for it is ‘strongAuthenticationAlternativePhoneNumber’ and its datatype is ‘String’. Rest for the confirmation code, there is no such defined attribute by default in Azure AD B2C as others specified earlier, but you can surely define a custom attribute for it by defining the ‘DisplayName’, ‘DataType’ and ‘UserInputType’ for the custom attribute as below: -
<!--
<BuildingBlocks>
<ClaimsSchema> -->
<ClaimType Id="city">
<DisplayName>City where you work</DisplayName>
<DataType>string</DataType>
<UserInputType>DropdownSingleSelect</UserInputType>
<Restriction>
<Enumeration Text="Berlin" Value="berlin" />
<Enumeration Text="London" Value="london" />
<Enumeration Text="Seattle" Value="seattle" />
</Restriction>
</ClaimType>
<!--
</ClaimsSchema>
</BuildingBlocks>-->
For more information regarding the above, please refer the below documentation links: -
https://learn.microsoft.com/en-us/azure/active-directory-b2c/configure-user-input?pivots=b2c-custom-policy#define-a-claim
https://learn.microsoft.com/en-us/azure/active-directory-b2c/user-profile-attributes

How to use Microsoft Graph to query the User source of authority in Azure B2C

I'm using Graph to query a user profile in Azure B2C. I'm able to query the users, but I don't see the Source field to determine the Source of Authority. What field is this?
I'm currently using the .28-preview of the Microsoft.Graph.Beta NuGet package.
And this is what I see in the debugger under Identities:
How would I tell the difference if that was a Google account or an Azure AD account?
Using Microsoft Graph, it’s the issuerId field within the Identities array and only returns on beta version.
Source is not included in the identities array, and is also not included in the properties.
As this issue with PowerShell shows, onPremisesSyncEnabled property will help.
I solved this by creating a custom attribute and then in the custom policies setting the custom attribute based on signup method (see alternative solution near the end).
How to define custom attributes and use them with the MS Graph API and custom policies is explained pretty well here. The hardest part is perhaps getting the custom policy right. I did everything in TrustFrameworkExtensions.xml. First defining an "extension_authoritySource" ClaimType:
<ClaimType Id="extension_AuthoritySource">
<DisplayName>AuthoritySource</DisplayName>
<DataType>string</DataType>
</ClaimType>
Then in <TechnicalProfile Id="Facebook-OAUTH"> I added an OutputClaim which sets this custom attribute to facebook, but this will only be persisted if a PersistedClaim is made in UserWriteUsingAlternativeSecurityId as shown below:
<OutputClaim ClaimTypeReferenceId="extension_AuthoritySource" DefaultValue="Facebook"/>
To persist the custom attribute I added the following to ClaimsProviders:
<ClaimsProvider>
<DisplayName>Azure Active Directory</DisplayName>
<TechnicalProfiles>
<TechnicalProfile Id="AAD-Common">
<Metadata>
<Item Key="ClientId">[b2c-extensions-app application ID]</Item>
<Item Key="ApplicationObjectId">[b2c-extensions-app application ObjectId]</Item>
</Metadata>
</TechnicalProfile>
<!-- Write data during a local account sign-up flow. -->
<TechnicalProfile Id="AAD-UserWriteUsingLogonEmail">
<PersistedClaims>
<PersistedClaim ClaimTypeReferenceId="extension_AuthoritySource" DefaultValue="local"/>
</PersistedClaims>
</TechnicalProfile>
<TechnicalProfile Id="AAD-UserWriteUsingAlternativeSecurityId">
<PersistedClaims>
<PersistedClaim ClaimTypeReferenceId="extension_AuthoritySource" DefaultValue="social"/>
</PersistedClaims>
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>
Note that with the above email signups will always be set as "local", while UserWriteUsingAlternativeSecurityId sets it as "social", but is overwritten by the output claim from facebook.
My thinking here is that UserWriteUsingLogonEmail is only ever used by email signup, whereas UserWriteUsingAlternativeSecurityId could potentially be used by several federated logins, although at the moment I only use facebook.
Alternative without Custom Attribute
Alternatively, if you are not using custom policies or cannot use the approach above for another reason, you can use the MS Graph API and look in the "identities" array which contains the sign in type. So for a given user GET: https://graph.microsoft.com/v1.0/users/[Users objectID Guid]?$select=identities
In this array you can find for a local signup:
{
"signInType": "emailAddress",
"issuer": "[yourdomain].onmicrosoft.com",
"issuerAssignedId": "[email]"
}
and for facebook:
{
"signInType": "federated",
"issuer": "facebook.com",
"issuerAssignedId": "[number]"
}
Every user also has a "userPrincipalName" item in the identities array so you will have to have some logic to loop through the array and only look for the signInType which you want to support. Yet another reason for preferring using custom attribute and setting the authority source yourself.

How to troubleshoot validation errors in Azure Active Directory B2C custom attributes

Azure AD B2C Custom Policy is failing validation and there is no reference to what is causing the validation error.
I already had custom policies defined for my application to start with and everything works fine prior to my adding a simple companyName string to the signup process. I followed the steps detailed in this guide to add a field to collect at signup. I ran into issues uploading the singup_signing custom policy after successfully uploading the TrustFrameworkBase policy. It was telling me that
Validation failed: 1 validation error(s) found in policy "B2C_1A_SIGNUP_SIGNIN" of tenant "xxxxx".Output Claim 'companyName' is not supported in Azure Active Directory Provider technical profile 'AAD-UserReadUsingObjectId' of policy 'B2C_1A_signup_signin'. If it is a claim with default value, add AlwaysUseDefaultValue="true" to the output claim mapping.
So I did as suggested and added the AlwaysUseDefaultValue="true" and DefaultValue="" attributes to the OutputClaim in the 'AAD-UserReadUsingObjectId' technical profile. This allowed me to upload the policy file successfully.
However, when I test the signup_signin policy, I get a message stating
Unable to validate the information provided.
I have Application Insights setup for this tenant as well and see the equally vague error message
Error returned was 400/Request_BadRequest: One or more property values specified are invalid.
I added the claim type to the claims schema in FrameworkBase
<ClaimType Id="companyName">
<DisplayName>Company</DisplayName>
<DataType>string</DataType>
<UserHelpText>Your company</UserHelpText>
<UserInputType>TextBox</UserInputType>
</ClaimType>
I added the PersistedClaim to TechnicalProfile 'AAD-UserWriteUsingLogonEmail'
<PersistedClaim ClaimTypeReferenceId="companyName" />
I added the OutputClaim to TechnicalProfiles 'AAD-UserReadUsingEmailAddress'
<OutputClaim ClaimTypeReferenceId="companyName" />
and 'AAD-UserReadUsingObjectId'
<OutputClaim ClaimTypeReferenceId="companyName" AlwaysUseDefaultValue="true" DefaultValue="" />
I added the OutputClaim to signup_signin.xml as well
<OutputClaim ClaimTypeReferenceId="companyName" />
I expect that the user is successfully signed up but get the validation error above instead
That example uses "city".
"Your Azure AD B2C directory comes with a built-in set of attributes. Examples are Given Name, Surname, City, Postal Code, and userPrincipalName."
So "city" is in the schema.
I assume from the error that "companyName" isn't.
To add that, you use a custom attribute.
So it would be "extension_companyName".

Azure B2C Custom Policy Has Create Button for SignUpSignIn and ProfileEdit Policies

I am currently experiencing a problem with Azure B2C IEF Custom Policy. In my "ProfileEdit" UserJourney The user is presented with the sign-in screen. The problem here is that the continue button is actually labeled "Create" After the user signs in, they are presented with a Edit Profile Page. But again, the continue button is labeled as create.
I have done a lot of research. I could not find anything in stackoverflow and I have reviewed Microsoft Documentation and also ensured that the DataURIs are correct for the ContentDefinition.
The current Data URI is as follows:
urn:com:microsoft:aad:b2c:elements:contract:selfasserted:1.1.0
Any guidance would be greatly appreciated.
if you don't want to go with localization. You can still update button/ label values inside Metadata of relevant technical profiles.
For your scenario
Add new Metadata Item in Base file technical profile
SelfAsserted-LocalAccountSignin-Email like below
<Metadata>
---
<Item Key="language.button_continue">Continue</Item>
</Metadata>
You can customize any element text using localization.
The first step is to enable localization for English and any other languages to be supported:
<BuildingBlocks>
...
<ContentDefinitions />
<Localization>
<SupportedLanguages DefaultLanguage="en">
<SupportedLanguage>en</SupportedLanguage>
</SupportedLanguages>
</Localization>
</BuildingBlocks>
The second step is to define the localized strings for each supported language for each page definition:
<BuildingBlocks>
...
<Localization>
<SupportedLanguages />
<LocalizedResources Id="api.selfasserted.profileupdate.en">
<LocalizedStrings>
<LocalizedString ElementType="UxElement" StringId="button_continue">Update</LocalizedString>
</LocalizedStrings>
</LocalizedResources>
</Localization>
</BuildingBlocks>
The last step is to declare references from the page definition to the localized resources:
<BuildingBlocks>
...
<ContentDefinitions>
<ContentDefinition Id="api.selfasserted.profileupdate">
...
<LocalizedResourcesReferences MergeBehavior="Prepend">
<LocalizedResourcesReference Language="en" LocalizedResourcesReferenceId="api.selfasserted.profileupdate.en" />
</LocalizedResourcesReferences>
</ContentDefinition>
</ContentDefinitions>
<Localization />
</BuildingBlocks>

How to obtain Azure AD Groups from B2C UserJourney?

I'm attempting to retrieve an AAD user's group membership when they log in to my B2C application.
What I've done:
Followed the procedures outlined in https://learn.microsoft.com/en-gb/azure/active-directory-b2c/active-directory-b2c-get-started-custom#add-the-application-ids-to-your-custom-policy
Created an application in my Azure AD tenant according to the instructions: https://learn.microsoft.com/en-gb/azure/active-directory-b2c/active-directory-b2c-setup-aad-custom
Modified the manifest of the application to support groups as discussed here -- https://www.red-gate.com/simple-talk/cloud/security-and-compliance/azure-active-directory-part-4-group-claims/
Created an attribute extension_groups in my B2C tenant for storing the groups (I do not know if this is necessary?)
Added a claimtype to TrustFrameworkBase.xml to support groups:
<ClaimType Id="extension_groups">
<DisplayName>Groups</DisplayName>
<DataType>string</DataType>
<DefaultPartnerClaimTypes>
<Protocol Name="OAuth2" PartnerClaimType="groups" />
<Protocol Name="OpenIdConnect" PartnerClaimType="groups" />
<Protocol Name="SAML2" PartnerClaimType="http://schemas.microsoft.com/ws/2008/06/identity/claims/groups" />
</DefaultPartnerClaimTypes>
<UserHelpText />
</ClaimType>
Modified the claims provider in TrustFrameworkExtensions.xml to include the group claim: <OutputClaim ClaimTypeReferenceId="extension_groups" PartnerClaimType="groups"/>
Modified the output claim in the relyingparty section of my sign-in-only policy:
<OutputClaim ClaimTypeReferenceId="extension_groups"/>
When I sign-in using using an Azure AD account, I get the following error:
Sorry, but we're 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. Correlation ID:
e782c5c8-0e08-481b-b2c1-458b3855af7b Timestamp: 2018-04-25 20:07:27Z
AADB2C: An exception has occured.
I'm not even sure where to start -- any tips on exposing the stack trace or hints based on the above config snippets would be amazing.
I think your problem is related to this https://feedback.azure.com/forums/169401-azure-active-directory/suggestions/10123836-get-user-membership-groups-in-the-claims-with-ad-b.

Resources