How to troubleshoot validation errors in Azure Active Directory B2C custom attributes - azure-ad-b2c

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".

Related

Custom policies Azure AD B2C issue with read the value Employee ID of user of Azure AD

I need help to solve a problem I have, we need to create a custom policy, which we already have created, but we need to read the value of the user's employeeid in Azure AD, so that when you sign in the first time, this is registered in B2C with that value. I put images to understand it:
Azure AD:
but when I sign in, the user in Azure AD B2C doesn't have the employeeid:
I defined in the custom policy the claim:
<ClaimType Id="extension_employeeid">
<DisplayName>EmployeeId</DisplayName>
<DataType>string</DataType>
<DefaultPartnerClaimTypes>
<Protocol Name="OAuth2" PartnerClaimType="employeeid" />
<Protocol Name="OpenIdConnect" PartnerClaimType="employeeid" />
<Protocol Name="SAML2" PartnerClaimType="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/employeeid" />
</DefaultPartnerClaimTypes>
<UserHelpText>Your EmployeeId. </UserHelpText>
<!--<UserInputType>Readonly</UserInputType>-->
<UserInputType>TextBox</UserInputType>
</ClaimType>
but the value of employeeid that is returned is empty.
How I can fix it?
Please check the User profile attributes in AAD B2C to get extension attributes for builtin attributes and employeeId is identifier attributes.
Use PersistedClaims to write data to the user profile i.e.; Write data during a federated account first-time sign-in flow and OutputClaims to read data from the user profile within the respective Active Directory technical profiles.
In your trustframeworkextensions file
<!-- Write data during a federated account first-time sign-in flow. -->
<TechnicalProfile Id="AAD-UserWriteUsingAlternativeSecurityId">
<InputClaims>
<InputClaim ClaimTypeReferenceId=" extension_EmployeeId " />
</InputClaims>
<PersistedClaims>
<PersistedClaim ClaimTypeReferenceId=" extension_EmployeeId " />
</PersistedClaims>
<OutputClaims>
ClaimTypeReferenceId="extension_EmployeeId" PartnerClaimType="extn.EmployeeId" " Required="true" />
</OutputClaims>
</TechnicalProfile>
Make TechnicalProfile Id =ā€¯AAD-UserReadUsingObjectIdā€¯ to Read data
after user authenticates with a local account.
If SAML is sending a claim "employeeId" than the mapping is
<OutputClaim ClaimTypeReferenceId="issuerUserId" PartnerClaimType="employeeId" />
Or try Technical Profile to output with PartnerClaimType as extension_employeeNumber
Also see Azure AD B2C: Custom claims with custom policies - Microsoft Q&A
Make sure to enable extension attributes in the custom policy,
provide Application ID and Application Object ID in the AAD-Common
technical profile metadata
Azure Active Directory
See: application properties
Please note that the Claim you set in SignUpOrSignin will be only
returned after your sign-up at that time. The custom attribute won't
be stored into Azure AD. Make sure to set the value of extension in
Base policy file .
References:
azure ad b2c - B2C SAML missing claims - Stack Overflow
Reading Extension Claims in Azure AD B2C - Stack Overflow

Understanding responses from just in time migration custom policy in Azure B2C

I have been slowly working through a custom policy to handle a JIT migration of an external IDP users to Azure B2C. It has been a long journey because there are many complexities in sorting out the components and the configuration steps using XML is a bit of a challenge. I am making some progress.
The basic use case is this: At sign in, the user/password is first checked against the B2C AD and if the user already exists just continue to sign in. If the user isn't in B2C AD, then check the external IDP with a REST call. I planned the response from the external IDP to be used in a binary way: If I get a 200 response, then add the user to B2C AD. If an error is returned then the user will be told to create an account.
I started with a couple of samples from a JIT Migration that I found. I had some difficulty navigating all the components with the social media logins, etc that I then reverted back to the "Local Accounts" sample found in the custom policy starterpack. I got the basic steps to work with no modification. I then added the technical profiles for the REST calls to the extensions file. I used the extension from one of the JIT migration samples and at least got the uploads to work. I am able to present a login prompt.
These are the scenarios and responses I see: 1) A user that I know is in B2C returns an error of "Unable to validate the information provided." 2) A user that I know is in the external IDP but not in B2C returns "We can't seem to find your account". 3) If I try a completely made up account that exists in neither, I see "The claims exchange 'REST-UserMigration-LocalAccount-SignIn' specified in step '1' returned HTTP error response with Code 'BadRequest' and Reason ''. "
So the question/struggle is how do I best sort out what is failing in each step. I have added app insights to the environment. I do see the traces in VS Code. But what should I look for? Here is the short responses ("Exceptions") for each of the errors listed above:
Scenario 1: The claim type "signInNames.emailAddress", designated as the identifier claim type, could not be found in the claims collection for the claims principal in tenant id "B2C_1A_JITMigration_signup_signin"
Scenario 2: A user with the specified credential could not be found.
Scenario 3: ErrorCodes: AADB2C90075
Rather than post of the code, here is the link to what I copied: https://github.com/azure-ad-b2c/user-migration/blob/master/jit-migration-v2/policy/TrustFrameworkExtensions.xml I can post up my exact code but basically I changed the tenant and the REST call. The Technical profile for the REST call snippet is:
<InputClaims>
<InputClaim ClaimTypeReferenceId="signInName" PartnerClaimType="username"/>
<InputClaim ClaimTypeReferenceId="password" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="needToMigrate" />
<OutputClaim ClaimTypeReferenceId="email" />
<OutputClaim ClaimTypeReferenceId="newPassword" />
<OutputClaim ClaimTypeReferenceId="displayName" />
<OutputClaim ClaimTypeReferenceId="givenName" />
<OutputClaim ClaimTypeReferenceId="surname" />
</OutputClaims>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
</TechnicalProfile>
The input claims are fine but I am not sure how to modify the output claims. The REST API returns a single value of an authentication token which I don't need but is an indication that the authentication succeeded. It returns an error if the authentication fails. Basically an HTTP 200 is good, an HTTP 400 means the user doesn't exist. The goal is to use that API call as a binary indicator to either migrate or not migrate the user. Perhaps I cannot use the API in that way.
My hope is to solve each scenario step by step. Figure out why the scenario 1 doesn't work although the credential are correct. Then figure out why scenario 2 is correctly identifying that the user isn't found but wasn't automatically migrated. Finally, to figure out how to manage the 400 error returned by the API when the user doesn't exist in the external IDP.
I might need to tweak the user journeys or orchestration steps? Taking baby steps here.
Thanks

Is there something special about B2C's givenName and surname claims? Can't read them from the OIDC ClaimsProvider

My OIDC claims provider (Okta) provides the given_name and family_name values to my OIDC test harness app.
My Azure B2C claims provider uses the same scopes as my test app, but I can't get the given_name and family_name to be added to the B2C claim,
Scopes used when calling Okta CP:
<Item Key="scope">openid profile email</Item>
OutputClaims mapping in Okta CP:
<OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="name" />
<OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="email" DefaultValue="default value from input ClaimsProvider: email"/>
<OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="given_name" DefaultValue="default value from input ClaimsProvider: givenName"/>
<OutputClaim ClaimTypeReferenceId="surname" PartnerClaimType="family_name" DefaultValue="default value from input ClaimsProvider: surname"/>
This configuration doesn't seem to get the values for these two claims. It does get the "name" and "email" values, so I feel confident the scopes are being honored. Using DefaultValues to debug, I see this in the Azure SAML test app.
SAML Login Success
Attribute Value
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress JoeBlow#xyz.com
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name Joe Blow
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname default value from input ClaimsProvider: givenName
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname default value from input ClaimsProvider: surname
http://schemas.microsoft.com/identity/claims/userprincipalname JoeBlow#xyz.com
Might be to late for the OP, but we just ran into this as well. It took us quite a while to find a solution.
Problem was not (in our case) the Azure AD B2C policy.
But instead the issue was with the Azure AD app registration (used for Ms + AAD accounts).
family_name+ given_name are optional claims
For those claims to be returned two things need to happen:
profile scope must be requested
configure the Azure AD app registration to return these 2 optional claims
This was the step we were missing
Here is the link to the doc explaining how to ensure an Azure AD app registration returns optional claims (its straight forward and only took 1min todo):
https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-optional-claims?WT.mc_id=AZ-MVP-5003445#configuring-optional-claims

How can I see data for users created by a custom policy?

I have Signup and Sinin custom policy that allow users to signup or signin. It works well.
The policy uses the following claims:
<OutputClaim ClaimTypeReferenceId="extension_firstName" />
<OutputClaim ClaimTypeReferenceId="extension_lastName" />
<OutputClaim ClaimTypeReferenceId="extension_organizationName" />
<OutputClaim ClaimTypeReferenceId="extension_contactPhoneNumber" />
<OutputClaim ClaimTypeReferenceId="extension_selectRole" />
<OutputClaim ClaimTypeReferenceId="extension_terms" />
When I goto B2C portal, find the user and look the user details, none of the extension_* claims (attributes or properties) appear there.
Then I use Microsoft Graph, issue this query:
https://graph.microsoft.com/v1.0/users/[user Object ID]
I get minimal data for the user. None of the extension_* calim data appears there.
How can I see all the extension_* claim data with a give user created by custom policy?
The Azure portal doesn't display the extension properties for users.
For the Microsoft Graph query, you must add the $select parameter in order to include the extension properties, such as:
GET https://graph.microsoft.com/v1.0/users/{id}?$select=extension_{b2cExtensionsAppClientId}_firstName,extension_{b2cExtensionsAppClientId}_lastName,...
where {b2cExtensionsAppClientId} is the application (client) identifier (without hyphens) for [the b2c-extensions-app application}(https://learn.microsoft.com/en-us/azure/active-directory-b2c/extensions-app) that is registered in your Azure AD B2C tenant such as:
extension_b2ba52d57b074a5e8fa2d8b35f5a1347_firstName

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