B2C RestfulProvider save entire response to outputClaim - azure-ad-b2c

I have an API that returns a list of strings:
[
"Some string",
"Some other string"
]
I need to consume this endpoint with a technical profile in Azure B2C.
How can i save the response to an OutputClaim?
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="{claimtype}" PartnerClaimType="<what to put here, if anything?>" />
</OutputClaims>

Currently it's not possible in Azure AD B2C to map a body made of a JSON array. Only fields from an flat object can be mapped to claims.

Related

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 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 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 get Facebook "age_range" and "gender" using Azure AD B2C

I'm currently using built-in attributes.
I'd like to get the "age_range" and "gender" from the FB.
Do I need to deal with custom policies as explained in the following topic:
how to get Facebook profile picture using Azure AD B2C
how to get Facebook profile picture using Azure AD B2C
to get them?
Thanks!
Yes, you will have to create a custom policy for that, and then:
1: Declare the "ageRange" and "gender" claim types in the extension file.
2: Add both the "age_range" and "gender" fields to the "ClaimsEndpoint" metadata item and the "ageRange" and "gender" output claims to the "Facebook-OAUTH" technical profile.
3: Issue the "ageRange" and "gender" claims in the relying party file.
If you are wanting to save the "age_range" and "gender" fields from Facebook as attributes to Azure AD B2C, then you must:
1: Follow the Azure Active Directory B2C: Creating and using custom attributes in a custom profile edit policy steps to create the custom attributes for "AgeRange" and "Gender".
2: Change the claim type declarations, as well as all other references to them, from "ageRange" and "gender" to "extension_AgeRange" and "extension_Gender".
3: Add the "extension_AgeRange" and "extension_Gender" claims in the extension file to the "AAD-UserWriteUsingAlternativeSecurityId" and "AAD-UserReadUsingAlternativeSecurityId" technical profile:
<ClaimsProvider>
<DisplayName>Facebook</DisplayName>
<TechnicalProfiles>
<TechnicalProfile Id="AAD-UserReadUsingAlternativeSecurityId">
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="extension_AgeRange" />
<OutputClaim ClaimTypeReferenceId="extension_Gender" />
</OutputClaims>
</TechnicalProfile>
<TechnicalProfile Id="AAD-UserWriteUsingAlternativeSecurityId">
<PersistedClaims>
<PersistedClaim ClaimTypeReferenceId="extension_AgeRange" />
<PersistedClaim ClaimTypeReferenceId="extension_Gender" />
</PersistedClaims>
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>

How do i include email in the redirect to AZURE AD B2C

I have set up an Azure B2C tenant and used custom policies to add azure ad as an IDP so that users can sign up with their domain accounts. I can build a custom page where ask them for their email and then redirect them to the proper policy(one for work domain accounts and another for personal emails), so that they do not have to make the choice between work and personal emails. The problem is that I do not want to make the user enter the email once again. Is there a way/option to do this? I basically want to achieve something similar to what the common endpoint of Azure AD does for all accounts.
For a custom policy, if you add the "login_hint" query string parameter to the OpenID Connect authentication request, then you can default the login field to this login hint by adding the "DefaultValue" attribute to the "signInName" input claim for the "SelfAsserted-LocalAccountSignin-Email" technical profile as follows:
<TechnicalProfile Id="SelfAsserted-LocalAccountSignin-Email">
<DisplayName>Local Account Signin</DisplayName>
...
<InputClaims>
<InputClaim ClaimTypeReferenceId="signInName" DefaultValue="{OIDC:LoginHint}" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="signInName" Required="true" />
...
</OutputClaims>
...
</TechnicalProfile>
The "DefaultValue" attribute references a claims resolver that sets the "signInName" claim type to the "login_hint" parameter of the OpenID Connect authentication request.
See the Set up direct sign-in using Azure Active Directory B2C article for more information about passing the "login_hint" query string parameter.

Resources