How to pass refresh token of a third party IDP to the application via Azure AD B2C? - azure-ad-b2c

I’m working on an application which can read files of a given OneDrive account.
We use Azure AD B2C as the identity provider. Users can login to the application using their Microsoft account. For that we have enabled Microsoft as an Identity Provider in my AAD B2C tenant.
When a given user is login using their Microsoft account, application should be able to get both access_token and refresh_token which enables us to communicate with MS Graph API, in order to fetch file details.
Using custom polices we were able to fetch access_token. However, we cannot fetch the refresh_token.
This is how ClaimsSchema is defined in TrustFrameworkExtensions.xml :
<ClaimsSchema>
<ClaimType Id="ms_access_token">
<DisplayName>MS access token</DisplayName>
<DataType>string</DataType>
<DefaultPartnerClaimTypes>
<Protocol Name="OAuth2" PartnerClaimType="{oauth2:access_token}" />
<Protocol Name="OpenIdConnect" PartnerClaimType="{oauth2:access_token}" />
</DefaultPartnerClaimTypes>
<UserHelpText>access token form 3rd party MS AD.</UserHelpText>
</ClaimType>
<ClaimType Id="ms_refresh_token">
<DisplayName>MS Refresh token</DisplayName>
<DataType>string</DataType>
<DefaultPartnerClaimTypes>
<Protocol Name="OAuth2" PartnerClaimType="{oauth2:refresh_token}" />
<Protocol Name="OpenIdConnect" PartnerClaimType="{oauth2:refresh_token}" />
</DefaultPartnerClaimTypes>
<UserHelpText>refresh token form 3rd party MS AD.</UserHelpText>
</ClaimType>
</ClaimsSchema>
Also in the same file, under the TechnicalProfile of Microsoft login, following OutputClaims node is added (some child nodes are removed for clarity):
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="ms_access_token" DefaultValue="" />
<OutputClaim ClaimTypeReferenceId="ms_refresh_token" DefaultValue="" />
</OutputClaims>
Then under the relevant RelyingParty node following OutputClaims node is added (some child nodes are removed for clarity):
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="ms_access_token" PartnerClaimType="ms_idp_access_token"/>
<OutputClaim ClaimTypeReferenceId="ms_refresh_token" PartnerClaimType="ms_idp_refresh_token"/>
</OutputClaims>
According to documentation there is no claim resolver for refresh_token.
Any suggestion to get this work?

I think that the only way you could do this would be via a custom api, that uses a password flow to authenticate the user. You can then return the refresh_token, access_token etc back from the API. I've not been able to figure any other way to do this.

Finally I was able to get this resolved by the help from a Microsoft employee in MS forum.
As of now, Azure AD B2C doesn't support this with OIDC providers. Therefore we have to enable Microsoft as an OAuth2 Identity Provider, instead of OIDC. For that we have to define a ClaimProvider like this:
<ClaimsProviders>
<ClaimsProvider>
<Domain>live.com</Domain>
<DisplayName>Microsoft Account</DisplayName>
<TechnicalProfiles>
<TechnicalProfile Id="MSA-OAuth">
<DisplayName>Microsoft Account</DisplayName>
<Protocol Name="OAuth2"/>
<OutputTokenFormat>JWT</OutputTokenFormat>
<Metadata>
<Item Key="AccessTokenEndpoint">https://login.live.com/oauth20_token.srf</Item>
<Item Key="authorization_endpoint">https://login.live.com/oauth20_authorize.srf</Item>
<Item Key="ClaimsEndpoint">https://graph.microsoft.com/v1.0/me</Item>
<Item Key="ClaimsEndpointAccessTokenName">access_token</Item>
<Item Key="BearerTokenTransmissionMethod">AuthorizationHeader</Item>
<Item Key="client_id"><!-- your client id --></Item>
<Item Key="HttpBinding">POST</Item>
<Item Key="scope">openid profile email offline_access files.read</Item>
<Item Key="UsePolicyInRedirectUri">0</Item>
</Metadata>
<CryptographicKeys>
<Key Id="client_secret" StorageReferenceId="B2C_1A_SampathAdCustomPolicyAppKey"/>
</CryptographicKeys>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="identityProvider" DefaultValue="live.com" />
<OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="socialIdpAuthentication" />
<OutputClaim ClaimTypeReferenceId="issuerUserId" PartnerClaimType="id"/>
<OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="name" />
<OutputClaim ClaimTypeReferenceId="email" />
<OutputClaim ClaimTypeReferenceId="ms_access_token" PartnerClaimType="{oauth2:access_token}"/>
<OutputClaim ClaimTypeReferenceId="ms_refresh_token" PartnerClaimType="{oauth2:refresh_token}"/>
</OutputClaims>
<OutputClaimsTransformations>
<OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName"/>
<OutputClaimsTransformation ReferenceId="CreateUserPrincipalName"/>
<OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId"/>
<OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromAlternativeSecurityId"/>
</OutputClaimsTransformations>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-SocialLogin" />
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>

Note that the {oauth2:refresh_token} claims resolver returns a JSON string such as:
{
"r": "<refresh_token>",
"d": "live.com"
}
You can read the r property from this JSON string as follows.
Create a GetClaimFromJson claims transformation:
<ClaimsTransformation Id="GetRefreshTokenFromRefreshTokenResult" TransformationMethod="GetClaimFromJson">
<InputClaims>
<InputClaim ClaimTypeReferenceId="ms_refresh_token" TransformationClaimType="inputJson" />
</InputClaims>
<InputParameters>
<InputParameter Id="claimToExtract" DataType="string" Value="r" />
</InputParameters>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="ms_refresh_token" TransformationClaimType="extractedClaim" />
</OutputClaims>
</ClaimsTransformation>
Invoke this claims transformation from the MSA-OAuth technical profile as an output claims transformation:
<OutputClaimsTransformations>
<OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName"/>
<OutputClaimsTransformation ReferenceId="CreateUserPrincipalName"/>
<OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId"/>
<OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromAlternativeSecurityId"/>
<OutputClaimsTransformation ReferenceId="GetRefreshTokenFromRefreshTokenResult" />
</OutputClaimsTransformations>

Related

email claim not coming from federated OIDC ADB2C IDP

We are using B2C and have successfully connected an AD federation using OIDC, that all works fine. However, we want to enable an external B2C IdP instance to enable another federation. We configured our host B2C the same as the AD one, getting the email, firstname, surname from the federation source.
Heres the technical profile to enable federation in our base.xml file
<ClaimsProvider>
<Domain>testdomain</Domain>
<DisplayName>Login using External Tenant</DisplayName>
<TechnicalProfiles>
<TechnicalProfile Id="TestDomain">
<DisplayName>Test domain</DisplayName>
<Description>Login with your test domain account</Description>
<Protocol Name="OpenIdConnect"/>
<Metadata>
<Item Key="METADATA">Link to the federated tenant well known endpoint</Item>
<Item Key="client_id">xxx</Item>
<Item Key="response_types">code</Item>
<Item Key="scope">openid email profile</Item>
<Item Key="response_mode">form_post</Item>
<Item Key="HttpBinding">POST</Item>
<Item Key="UsePolicyInRedirectUri">false</Item>
<Item Key="ClaimTypeOnWhichToEnable">identityProviders</Item>
<Item Key="ClaimValueOnWhichToEnable">testdomain</Item>
</Metadata>
<CryptographicKeys>
<Key Id="client_secret" StorageReferenceId="testdomain"/>
</CryptographicKeys>
<InputClaims>
<InputClaim ClaimTypeReferenceId="signInName" PartnerClaimType="login_hint" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="issuerUserId" PartnerClaimType="sub"/>
<OutputClaim ClaimTypeReferenceId="tenantId" PartnerClaimType="tid"/>
<OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="given_name" />
<OutputClaim ClaimTypeReferenceId="surName" PartnerClaimType="family_name" />
<OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="name" />
<OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="socialIdpAuthentication" AlwaysUseDefaultValue="true" />
<OutputClaim ClaimTypeReferenceId="identityProvider" PartnerClaimType="iss" />
<OutputClaim ClaimTypeReferenceId="objectIdExternalTenant" PartnerClaimType="sub" />
<OutputClaim ClaimTypeReferenceId="email" />
<OutputClaim ClaimTypeReferenceId="federatedGivenName" PartnerClaimType="given_name" DefaultValue="Not Set"/>
<OutputClaim ClaimTypeReferenceId="federatedSurname" PartnerClaimType="family_name" DefaultValue="Not Set"/>
<OutputClaim ClaimTypeReferenceId="federatedDisplayName" PartnerClaimType="name" DefaultValue="Not Set"/>
<OutputClaim ClaimTypeReferenceId="federatedIDPEmailAddress" PartnerClaimType="email" DefaultValue="Not Set"/>
</OutputClaims>
<OutputClaimsTransformations>
<OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName"/>
<OutputClaimsTransformation ReferenceId="CreateUserPrincipalName"/>
<OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId"/>
<OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromAlternativeSecurityId"/>
</OutputClaimsTransformations>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-SocialLogin"/>
<EnabledForUserJourneys>OnItemExistenceInStringCollectionClaim</EnabledForUserJourneys>
</TechnicalProfile>
Here's the setup for the app registration on the federation idp side. Note the settings saying you can only enable openid and offline_access scopes.
See attached pictures
fed1
fed2
When we login through our home realm discover page, it takes us to the federated Idp, we login to that but we cannot get the email claim back, given_name, family_name, name, sub are all there but it doesn't populate the email claim. Any ideas why this claim won't come through?
Thanks in advance.
Instead of "email", try "signInNames.emailAddress".
Search your TrustFrameworkBase.xml file for "signInNames.emailAddress" to confirm that it is there.
Here is a list of user attributes:
https://learn.microsoft.com/en-us/azure/active-directory-b2c/user-profile-attributes

Azure b2c custom policy, LinkedIn Identity Provider, unable to get email address

I want to add LinkedIn as an identity provider to my azure b2c tenant.
I have already added Microsoft and Google as id providers.
However, when I added LinkedIn, it was impossible to retrieve an email address and put it in the azure b2c token.
Here is my custom policy base file: TrustFrameworkBase.xml
<ClaimsProvider>
<Domain>linkedin.com</Domain>
<DisplayName>LinkedIn</DisplayName>
<TechnicalProfiles>
<TechnicalProfile Id="LinkedIn-OAuth2">
<DisplayName>LinkedIn</DisplayName>
<Protocol Name="OAuth2" />
<Metadata>
<Item Key="ProviderName">linkedin</Item>
<Item Key="authorization_endpoint">https://www.linkedin.com/oauth/v2/authorization</Item>
<Item Key="AccessTokenEndpoint">https://www.linkedin.com/oauth/v2/accessToken</Item>
<Item Key="ClaimsEndpoint">https://api.linkedin.com/v2/me</Item>
<Item Key="scope">r_emailaddress r_liteprofile</Item>
<Item Key="HttpBinding">POST</Item>
<Item Key="external_user_identity_claim_id">id</Item>
<Item Key="BearerTokenTransmissionMethod">AuthorizationHeader</Item>
<Item Key="ResolveJsonPathsInJsonTokens">true</Item>
<Item Key="UsePolicyInRedirectUri">false</Item>
<Item Key="client_id">MyLinkedInClientId</Item>
</Metadata>
<CryptographicKeys>
<Key Id="client_secret" StorageReferenceId="B2C_1A_LinkedInSecret" />
</CryptographicKeys>
<InputClaims />
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="issuerUserId" PartnerClaimType="id" />
<OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="firstName.localized" />
<OutputClaim ClaimTypeReferenceId="surname" PartnerClaimType="lastName.localized" />
<OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="emailAddress" />
<OutputClaim ClaimTypeReferenceId="identityProvider" DefaultValue="linkedin.com" AlwaysUseDefaultValue="true" />
<OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="socialIdpAuthentication" AlwaysUseDefaultValue="true" />
</OutputClaims>
<OutputClaimsTransformations>
<OutputClaimsTransformation ReferenceId="ExtractGivenNameFromLinkedInResponse" />
<OutputClaimsTransformation ReferenceId="ExtractSurNameFromLinkedInResponse" />
<OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName" />
<OutputClaimsTransformation ReferenceId="CreateUserPrincipalName" />
<OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId" />
<OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromAlternativeSecurityId" />
</OutputClaimsTransformations>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-SocialLogin" />
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>
As we can see, the ClaimsEndPoint is https://api.linkedin.com/v2/me
But, this end point does not give access to the email address.
Here is the documentation detailing it:
Sign-in with linked-in
We see that to get the email address, we need to call another end point: https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))
I tried changing the ClaimsEndPoint to this but when uploading the custom policy, I got an error:
The policy being uploaded is not correctly formatted: '=' is an unexpected token.
I don't see what I could do to get the email address as a claim in the azure b2c token.
Can you please help?
As per this, you need to make an additional API call and pass the access token you already have.

Unable to pass query param to azure-ad-b2c custom policy and store values

I have a scenario where i have to pass a query parameter in the URL to my custom sign-up policy and so far all my attempts did not work. there seem to be something that i am missing following the guidelines i found in github. I am trying to pass LoyaltyNumber and i have this attribute defined in my policy as extension_LoyaltyNumber. Below is the snippet
my custom signup policy
<RelyingParty>
<DefaultUserJourney ReferenceId="SignUp" />
<UserJourneyBehaviors>
<ContentDefinitionParameters>
<Parameter Name="LoyaltyNumber">{OAUTH-KV:LoyaltyNumber}</Parameter>
</ContentDefinitionParameters>
</UserJourneyBehaviors>
<TechnicalProfile Id="PolicyProfile">
<DisplayName>PolicyProfile</DisplayName>
<Protocol Name="OpenIdConnect" />
<InputClaims>
<InputClaim ClaimTypeReferenceId="email" />
<InputClaim ClaimTypeReferenceId="extension_LoyaltyNumber" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="displayName" />
<OutputClaim ClaimTypeReferenceId="givenName" />
<OutputClaim ClaimTypeReferenceId="surname" />
<OutputClaim ClaimTypeReferenceId="signInNames.emailAddress" PartnerClaimType="email" />
<OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub"/>
<OutputClaim ClaimTypeReferenceId="tenantId" AlwaysUseDefaultValue="true" DefaultValue="{Policy:TenantObjectId}" />
<OutputClaim ClaimTypeReferenceId="extension_ValidPassword" />
<OutputClaim ClaimTypeReferenceId="extension_LoyaltyNumber" AlwaysUseDefaultValue="true"/>
</OutputClaims>
<SubjectNamingInfo ClaimType="sub" />
</TechnicalProfile>
in my TrustFrameworkExtension.xml, i have defined it in the Local Account as follows
<ClaimsProvider>
<DisplayName>Local Account</DisplayName>
<TechnicalProfiles>
<!--Local account sign-up page-->
<TechnicalProfile Id="LocalAccountSignUpWithLogonEmail">
<Metadata>
<Item Key="IncludeClaimResolvingInClaimsHandling">true</Item>
</Metadata>
<InputClaims>
<InputClaim ClaimTypeReferenceId="extension_LoyaltyNumber" AlwaysUseDefaultValue="true" DefaultValue="{OAUTH-K:LoyaltyNumber}" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="Verified.Email" Required="true" />
<OutputClaim ClaimTypeReferenceId="newPassword" Required="true" />
<OutputClaim ClaimTypeReferenceId="reenterPassword" Required="true" />
<OutputClaim ClaimTypeReferenceId="displayName" />
<OutputClaim ClaimTypeReferenceId="givenName" />
<OutputClaim ClaimTypeReferenceId="surName" />
</OutputClaims>
</TechnicalProfile>
<TechnicalProfile Id="SelfAsserted-LocalAccountSignin-Email">
<Metadata>
<Item Key="setting.showSignupLink">false</Item>
</Metadata>
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>
i also have it in the building bolocks section as...
<BuildingBlocks>
<ClaimsSchema>
<ClaimType Id="extension_LoyaltyNumber">
<DisplayName>Loyality-Number</DisplayName>
<DataType>string</DataType>
<UserHelpText>Your loyality from your membership card</UserHelpText>
</ClaimType>
</ClaimsSchema>
</BuildingBlocks>
i have it also to write to Azure Active Directory claims provider section as follows
<ClaimsProvider>
<DisplayName>Azure Active Directory</DisplayName>
<TechnicalProfiles>
<TechnicalProfile Id="AAD-Common">
<Metadata>
<!--Insert b2c-extensions-app application ID here, for example: 11111111-1111-1111-1111-111111111111-->
<Item Key="ClientId">11111111-1111-1111-1111-111111111111</Item>
<!--Insert b2c-extensions-app application ObjectId here, for example: 22222222-2222-2222-2222-222222222222-->
<Item Key="ApplicationObjectId">22222222-2222-2222-2222-222222222222</Item>
</Metadata>
</TechnicalProfile>
<TechnicalProfile Id="AAD-UserWriteUsingLogonEmail">
<PersistedClaims>
<PersistedClaim ClaimTypeReferenceId="extension_LoyaltyNumber" />
</PersistedClaims>
</TechnicalProfile>
<TechnicalProfile Id="AAD-UserReadUsingObjectId">
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="extension_LoyaltyNumber" />
</OutputClaims>
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>
And the redirect happens from my web application using the following method
public void SignUpNewUser()
{
if (!Request.IsAuthenticated)
{
var authenticationProperties = new AuthenticationProperties();
authenticationProperties.Dictionary.Add("LoyaltyNumber", "556677");
authenticationProperties.RedirectUri = "/";
HttpContext.GetOwinContext().Authentication.Challenge(authenticationProperties, Startup.SignUpPolicyId);
}
}
The result i am getting after the user sign-up for the custom attribute extension_LoyaltyNumber is {OAUTH-K:LoyaltyNumber}
Somehow the value 556677 i pass as a query param is not getting to this custom attribute and get stored in Azure user attribute
Can you help?
Thanks
Add
<OutputClaim ClaimTypeReferenceId="extension_LoyaltyNumber" />
to LocalAccountSignUpWithLogonEmail. Output claims allow the claim to be used in subsequent orchestration steps.
In the <RelyingParty> section, change your output claim to the following, its already resolved so no need to resolve it again here:
<OutputClaim ClaimTypeReferenceId="extension_LoyaltyNumber" />
What I do when I want to have query string parameters handled is this:
Create a TechnicalProfile:
<TechnicalProfile Id="GetMyParameter">
<DisplayName>GetMyParameter</DisplayName>
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.ClaimsTransformationProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
<Metadata>
<Item Key="IncludeClaimResolvingInClaimsHandling">true</Item>
</Metadata>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="myParameter" AlwaysUseDefaultValue="true" DefaultValue="{OAUTH-KV:myparameter}" />
</OutputClaims>
</TechnicalProfile>
Then run that profile in an OrchestrationStep before the claim value is required (it can be the first one or somewhere later along the way, doesn't matter much as far as I can tell).
You can have as many parameters in the technical profile as you wish. Works every time, doesn't crash if you don't provide value.
I Faced with the same problem, and found answer in official documentation
Don't forget to create claimType in your claims schema
<ClaimType Id="q_param">
<DisplayName>q_param</DisplayName>
<DataType>string</DataType>
<UserHelpText>Special parameter passed for authentication context</UserHelpText>
</ClaimType>
Additionally you need to set output claim in technical profile like in example
from TrustFrameworkExtensions.xml
<ClaimsProvider>
<DisplayName>Local Account SignIn</DisplayName>
<TechnicalProfiles>
<TechnicalProfile Id="login-NonInteractive">
<Metadata>
<Item Key="client_id">ProxyIdentityExperienceFrameworkAppId</Item>
<Item Key="IdTokenAudience">IdentityExperienceFrameworkAppId</Item>
</Metadata>
<InputClaims>
<InputClaim ClaimTypeReferenceId="client_id" DefaultValue="ProxyIdentityExperienceFrameworkAppId" />
<InputClaim ClaimTypeReferenceId="resource_id" PartnerClaimType="resource" DefaultValue="IdentityExperienceFrameworkAppId" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="q_param" DefaultValue="{OAUTH-KV:q_param}" />
</OutputClaims>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-AAD" />
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>

Azure B2C custom policy REST API CALL not working for Microsoft account

I have added Microsoft IDP to Custom Policy using this link [https://learn.microsoft.com/en-us/azure/active-directory-b2c/identity-provider-microsoft-account-custom?tabs=applications][1].
The user can click the Microsoft Account button and use their MSA account to sign-up\sign-in.
When the user signs up using MS acccount we'd like to validate the e-mail against our database. If the user's email is in our database, let them proceed and signup; otherwise we'd like to prevent them from signing up and display an error message. This would prevent creating a User in our Azure B2C AD.
I used the following TechnicalProfile in
<ClaimsProvider>
<Domain>live.com</Domain>
<DisplayName>Microsoft Account</DisplayName>
<TechnicalProfiles>
<TechnicalProfile Id="MSA-OIDC">
<DisplayName>Microsoft Account</DisplayName>
<Protocol Name="OpenIdConnect" />
<Metadata>
<Item Key="ProviderName">https://login.live.com</Item>
<Item Key="METADATA">https://login.live.com/.well-known/openid-configuration</Item>
<Item Key="response_types">code</Item>
<Item Key="response_mode">form_post</Item>
<Item Key="scope">openid profile email</Item>
<Item Key="HttpBinding">POST</Item>
<Item Key="UsePolicyInRedirectUri">0</Item>
<Item Key="client_id">12344</Item>
</Metadata>
<CryptographicKeys>
<Key Id="client_secret" StorageReferenceId="B2C_1A_MSASecret" />
</CryptographicKeys>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="issuerUserId" PartnerClaimType="oid" />
<OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="given_name" />
<OutputClaim ClaimTypeReferenceId="surName" PartnerClaimType="family_name" />
<OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="name" />
<OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="socialIdpAuthentication" />
<OutputClaim ClaimTypeReferenceId="identityProvider" PartnerClaimType="iss" />
<OutputClaim ClaimTypeReferenceId="email" />
</OutputClaims>
<OutputClaimsTransformations>
<OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName" />
<OutputClaimsTransformation ReferenceId="CreateUserPrincipalName" />
<OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId" />
<OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromAlternativeSecurityId" />
</OutputClaimsTransformations>
<ValidationTechnicalProfiles>
<ValidationTechnicalProfile ReferenceId="REST-ValidateProfile" />
</ValidationTechnicalProfiles>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-SocialLogin" />
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>
i added REST API Call
<ValidationTechnicalProfiles>
<ValidationTechnicalProfile ReferenceId="REST-ValidateProfile" />
</ValidationTechnicalProfiles>
but is not working.
ANy idea?
Check whether you mentioned the Self Asserted Technical profile in ths custom policy which collects the user details submitted to b2c and you can validate the email using the REST API.
for more information you can through these articles
REST API Claims exchange integration with user journey to validate user input
LocalAndSocialAccount Sign In and Sign Up policy wiki
and there is a similar discussion related to validating the user input data

Json type claim in Azure AD B2C custom policies

I am using Azure AD B2C custom policies to get claims from a third party and map it to the claims which are returned in the Azure AD B2C token.
If the third party returns claims in the form of string, my User journey in the policy works fine. My problem is that the third party is returning the claims in the form of json. I couldn't find any relavant in the B2C policy's XML Schema that can handle this case.
Is there any way to do this using Azure AD B2C Custom policies ?
Though I don't know what third part identity provider you're using, but I think you can achieve add the provider by adding custom providers in custom policies.
First, according to your post , I assume that you're using the Oauth/OIDC provider.
Example: Add LinkedIn as an identity provider by using custom policies:
In the <ClaimsProviders> element, add the following XML snippet:
<ClaimsProvider>
<Domain>linkedin.com</Domain>
<DisplayName>LinkedIn</DisplayName>
<TechnicalProfiles>
<TechnicalProfile Id="LinkedIn-OAUTH">
<DisplayName>LinkedIn</DisplayName>
<Protocol Name="OAuth2" />
<Metadata>
<Item Key="ProviderName">linkedin</Item>
<Item Key="authorization_endpoint">https://www.linkedin.com/oauth/v2/authorization</Item>
<Item Key="AccessTokenEndpoint">https://www.linkedin.com/oauth/v2/accessToken</Item>
<Item Key="ClaimsEndpoint">https://api.linkedin.com/v1/people/~:(id,first-name,last-name,email-address,headline)</Item>
<Item Key="ClaimsEndpointAccessTokenName">oauth2_access_token</Item>
<Item Key="ClaimsEndpointFormatName">format</Item>
<Item Key="ClaimsEndpointFormat">json</Item>
<Item Key="scope">r_emailaddress r_basicprofile</Item>
<Item Key="HttpBinding">POST</Item>
<Item Key="UsePolicyInRedirectUri">0</Item>
<Item Key="client_id">Your LinkedIn application client ID</Item>
</Metadata>
<CryptographicKeys>
<Key Id="client_secret" StorageReferenceId="B2C_1A_LinkedInSecret" />
</CryptographicKeys>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="socialIdpUserId" PartnerClaimType="id" />
<OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="firstName" />
<OutputClaim ClaimTypeReferenceId="surname" PartnerClaimType="lastName" />
<OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="emailAddress" />
<!--<OutputClaim ClaimTypeReferenceId="jobTitle" PartnerClaimType="headline" />-->
<OutputClaim ClaimTypeReferenceId="identityProvider" DefaultValue="linkedin.com" />
<OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="socialIdpAuthentication" />
</OutputClaims>
<OutputClaimsTransformations>
<OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName" />
<OutputClaimsTransformation ReferenceId="CreateUserPrincipalName" />
<OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId" />
<OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromAlternativeSecurityId" />
</OutputClaimsTransformations>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-SocialLogin" />
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>
Also, you can add <Item Key="AccessTokenResponseFormat">json</Item> to claim json type of endpoint.
You can see more details about Adding LinkedIn as an identity provider by using custom policies in this document.
Additional:
I don't know what third identity provider you're using , if it helps ,please let me know.

Resources