Azure AD B2C - Custom Provider for GitHub cannot get access token - azure

I am setting up GitHub as a custom provider in Azure AD B2C using custom policies. I am able to get to the login page and successfully redirect back to the correct azure ad link, but a server error in Azure AD B2C always rejects the second part of OAUTH.
When I look at the app insights trace logs, it says "An invalid OAuth response was received" and "Unexpected character encountered while parsing value: a" is encountered. Here is the policy provider I set up:
<ClaimsProvider>
<Domain>github.com</Domain>
<DisplayName>GitHub</DisplayName>
<TechnicalProfiles>
<TechnicalProfile Id="GitHub-OAUTH">
<DisplayName>GitHub</DisplayName>
<Protocol Name="OAuth2" />
<Metadata>
<Item Key="ProviderName">github</Item>
<Item Key="authorization_endpoint">https://github.com/login/oauth/authorize</Item>
<Item Key="AccessTokenEndpoint">https://github.com/login/oauth/access_token?</Item>
<Item Key="HttpBinding">POST</Item>
<Item Key="ClaimsEndpoint">https://api.github.com/user</Item>
<Item Key="client_id">My Client Id</Item>
<Item Key="UsePolicyInRedirectUri">0</Item>
<Item Key="scope">user</Item>
<Item Key="response_types">code</Item>
</Metadata>
<CryptographicKeys>
<Key Id="client_secret" StorageReferenceId="B2C_1A_GitHubSecret" />
</CryptographicKeys>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="socialIdpUserId" PartnerClaimType="id" />
<OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="email" />
<OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="name" />
<OutputClaim ClaimTypeReferenceId="identityProvider" DefaultValue="github.com" />
<OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="socialIdpAuthentication" />
</OutputClaims>
<OutputClaimsTransformations>
<OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName" />
<OutputClaimsTransformation ReferenceId="CreateUserPrincipalName" />
<OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId" />
</OutputClaimsTransformations>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-SocialLogin" />
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>
I wonder if the issue is that the access_token is not returned in a json? I stepped through all of the steps myself in postman, and the code was returned as a url parameter, and the access_token was returned in the body of the response like this:
access_token=<snip>&scope=user%3Aemail&token_type=bearer
Am I missing a metadata item in the custom provider to support this response? Or does this just not work in Azure AD B2C?

Yes, it is because the access token response is encoded as a HTML form, rather than JSON.
Following is how to integrate with GitHub.
1) Add a claim type for the GitHub user identifier of type long:
<ClaimType Id="gitHubUserId">
<DisplayName>GitHub User ID</DisplayName>
<DataType>long</DataType>
</ClaimType>
2) Add a claims transformation for converting from the GitHub user identifier of type long to the Azure AD B2C social user identifier of type string:
<ClaimsTransformation Id="CreateAlternativeSecurityUserIdForGitHub" TransformationMethod="ConvertNumberToStringClaim">
<InputClaims>
<InputClaim ClaimTypeReferenceId="gitHubUserId" TransformationClaimType="inputClaim" />
</InputClaims>
<InputParameters>
<InputParameter Id="stringFormat" DataType="string" Value="{0}" />
</InputParameters>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="socialIdpUserId" TransformationClaimType="outputClaim" />
</OutputClaims>
</ClaimsTransformation>
3) Add the technical profile for the GitHub OAuth flow:
<TechnicalProfile Id="GitHub-OAUTH">
<DisplayName>GitHub</DisplayName>
<Protocol Name="OAuth2" />
<Metadata>
<Item Key="ProviderName">github.com</Item>
<Item Key="authorization_endpoint">https://github.com/login/oauth/authorize</Item>
<Item Key="AccessTokenEndpoint">https://github.com/login/oauth/access_token</Item>
<Item Key="HttpBinding">GET</Item>
<Item Key="ClaimsEndpoint">https://api.github.com/user</Item>
<Item Key="client_id">Insert the client identifier</Item>
<Item Key="scope">user</Item>
<Item Key="UserAgentForClaimsExchange">CPIM-Basic/{tenant}/{policy}</Item>
</Metadata>
<CryptographicKeys>
<Key Id="client_secret" StorageReferenceId="B2C_1A_GitHubSecret" />
</CryptographicKeys>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="gitHubUserId" PartnerClaimType="id" />
<OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="email" />
<OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="name" />
<OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="socialIdpAuthentication" />
<OutputClaim ClaimTypeReferenceId="identityProvider" DefaultValue="github.com" />
</OutputClaims>
<OutputClaimsTransformations>
<OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName" />
<OutputClaimsTransformation ReferenceId="CreateUserPrincipalName" />
<OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityUserIdForGitHub" />
<OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId" />
</OutputClaimsTransformations>
<UseTechnicalProfileForSessionManagement ReferenceId="SSOSession-Noop" />
</TechnicalProfile>

Related

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.

Azure AD B2C Custom policy for terms and condition with open id connect protocol

I am using this example https://github.com/azure-ad-b2c/samples/tree/master/policies/sign-in-sign-up-versioned-tou to implement Terms and Condition custom policy for Azure AD B2C user which is working fine
I have another flow which integrates Azure AD Users as well which works on Open ID connect protocol I am try to implement same flow. But when implementing I get protocol error
Invalid technical profile with id "AADProvider-OpenIdConnect" only the protocol handler ""Web.TPEngine.Providers.SelfAssertedAttributeProvider"" can have a ValidationTechnicalProfile.Invalid technical profile with id "AADProvider-OpenIdConnect" only the protocol handler ""Web.TPEngine.Providers.SelfAssertedAttributeProvider"" can have a ValidationTechnicalProfile.
Below is my sample Technical profile
<ClaimsProvider>
<Domain>Contoso</Domain>
<DisplayName>Login using Contoso</DisplayName>
<TechnicalProfiles>
<TechnicalProfile Id="AADContoso-OpenIdConnect">
<DisplayName>Contoso Employee</DisplayName>
<Description>Login with your Contoso account</Description>
<Protocol Name="OpenIdConnect"/>
<Metadata>
<Item Key="METADATA">https://login.microsoftonline.com/tenant-name.onmicrosoft.com/v2.0/.well-known/openid-configuration</Item>
<Item Key="client_id">00000000-0000-0000-0000-000000000000</Item>
<Item Key="response_types">code</Item>
<Item Key="scope">openid profile</Item>
<Item Key="response_mode">form_post</Item>
<Item Key="HttpBinding">POST</Item>
<Item Key="UsePolicyInRedirectUri">false</Item>
</Metadata>
<CryptographicKeys>
<Key Id="client_secret" StorageReferenceId="B2C_1A_ContosoAppSecret"/>
</CryptographicKeys>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="issuerUserId" PartnerClaimType="oid"/>
<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="extension_TOUConsentChoice" Required="true" />
</OutputClaims>
<ValidationTechnicalProfiles>
<ValidationTechnicalProfile ReferenceId="AAD-UserWriteUsingLogonEmail" />
</ValidationTechnicalProfiles>
<OutputClaimsTransformations>
<OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName"/>
<OutputClaimsTransformation ReferenceId="CreateUserPrincipalName"/>
<OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId"/>
<OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromAlternativeSecurityId"/>
</OutputClaimsTransformations>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-SocialLogin"/>
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>
Is there any work around for this

Getting Refresh Token in Azure B2C, with Azure AD App being the third party IDP

We have a Web App and the users authenticate via Azure B2C. We added an Azure AD App as Claims Provider. So our users should be able to login via local accounts and Azure AD accounts. For the ones that login via Azure AD App we'd like to get the access and refresh token, to be able to make calls to the Microsoft Graph. Getting the access token works, but the refresh token is not sent.
This is the custom policy TrustFrameworkExtensions.xml:
<ClaimsProvider>
<Domain>azuread</Domain>
<DisplayName>azure AD app</DisplayName>
<TechnicalProfiles>
<TechnicalProfile Id="AADCommon-OpenIdConnect">
<DisplayName>Azure AD</DisplayName>
<Description>Login with your Azure AD account</Description>
<Protocol Name="OpenIdConnect"/>
<Metadata>
<Item Key="METADATA">https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration</Item>
<Item Key="client_id">CLIENT-ID</Item>
<Item Key="response_types">code</Item>
<Item Key="scope">openid profile offline_access</Item>
<Item Key="response_mode">form_post</Item>
<Item Key="HttpBinding">POST</Item>
<Item Key="UsePolicyInRedirectUri">false</Item>
<Item Key="DiscoverMetadataByTokenIssuer">true</Item>
<Item Key="ValidTokenIssuerPrefixes">https://login.microsoftonline.com/</Item>
</Metadata>
<CryptographicKeys>
<Key Id="client_secret" StorageReferenceId="B2C_1A_azureadappkey"/>
</CryptographicKeys>
<OutputClaims>
...
<OutputClaim ClaimTypeReferenceId="identityProviderAccessToken" PartnerClaimType="{oauth2:access_token}" />
<OutputClaim ClaimTypeReferenceId="identityProviderRefreshToken" PartnerClaimType="{oauth2:refresh_token}"/>
</OutputClaims>
<OutputClaimsTransformations>
...
</OutputClaimsTransformations>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-SocialLogin"/>
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>
And signup_signin.xml looks like this:
<RelyingParty>
<DefaultUserJourney ReferenceId="SignUpOrSignIn" />
<TechnicalProfile Id="PolicyProfile">
<DisplayName>PolicyProfile</DisplayName>
<Protocol Name="OpenIdConnect" />
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="displayName" />
<OutputClaim ClaimTypeReferenceId="givenName" />
<OutputClaim ClaimTypeReferenceId="surname" />
<OutputClaim ClaimTypeReferenceId="email" />
<OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub" />
<OutputClaim ClaimTypeReferenceId="tenantId" AlwaysUseDefaultValue="true" DefaultValue="{Policy:TenantObjectId}" />
<OutputClaim ClaimTypeReferenceId="identityProviderAccessToken" PartnerClaimType="idp_access_token"/>
<OutputClaim ClaimTypeReferenceId="identityProviderRefreshToken" PartnerClaimType="idp_refresh_token"/>
</OutputClaims>
<SubjectNamingInfo ClaimType="sub" />
</TechnicalProfile>
In the claims of the user, there is the access token in idp_access_token, but nothing for idp_refresh_token.
What do I have to change to get the Refresh Token as well?
Turns out that you need to switch protocol for the Technical Profile from "OpenIdConnect" to "OAuth2" and specify the various endpoints yourself:
<TechnicalProfile Id="AADCommon-OpenIdConnect">
<DisplayName>Company Azure AD</DisplayName>
<Description>Login with your Company Azure AD</Description>
<Protocol Name="OAuth2"/>
<OutputTokenFormat>JWT</OutputTokenFormat>
<Metadata>
<Item Key="AccessTokenEndpoint">https://login.microsoftonline.com/common/oauth2/v2.0/token</Item>
<Item Key="authorization_endpoint">https://login.microsoftonline.com/common/oauth2/v2.0/authorize</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">CLIENT-ID</Item>
<Item Key="HttpBinding">POST</Item>
<Item Key="scope">offline_access openid</Item>
<Item Key="UsePolicyInRedirectUri">0</Item>
</Metadata>
<CryptographicKeys>
<Key Id="client_secret" StorageReferenceId="B2C_1A_azureadappkey"/>
</CryptographicKeys>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="issuerUserId" PartnerClaimType="id" />
<OutputClaim ClaimTypeReferenceId="tenantId" PartnerClaimType="tid"/>
<OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="givenName" />
<OutputClaim ClaimTypeReferenceId="surName" PartnerClaimType="surname" />
<OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="displayName" />
<OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="socialIdpAuthentication" AlwaysUseDefaultValue="true" />
<OutputClaim ClaimTypeReferenceId="identityProvider" PartnerClaimType="iss" DefaultValue="azuread" />
<OutputClaim ClaimTypeReferenceId="identityProviderAccessToken" PartnerClaimType="{oauth2:access_token}" />
<OutputClaim ClaimTypeReferenceId="identityProviderRefreshToken" PartnerClaimType="{oauth2:refresh_token}"/>
</OutputClaims>
<OutputClaimsTransformations>
<OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName"/>
<OutputClaimsTransformation ReferenceId="CreateUserPrincipalName"/>
<OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId"/>
<OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromAlternativeSecurityId"/>
</OutputClaimsTransformations>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-SocialLogin"/>
</TechnicalProfile>
That way, the refresh token ends up in the user's claims:
I looked at this last year and it's not possible, as only the access token is returned.
https://learn.microsoft.com/en-us/azure/active-directory-b2c/idp-pass-through-user-flow?pivots=b2c-custom-policy

Sign in email domain validation in Azure AD B2C

I am using microsoft authentication using the steps shown in the this link.
This opens a Microsoft SSO page to sign in which works as expected. This allows us to sign in through different microsoft hosted emails such as your-email#hotmail.com, your-email#outlook.com etc. What I want to do now is to add a validation to make the email domain bound for example only allow #outlook.com users to sign in. How can we do this using custom policy?
We tried adding following code suggested in this link:
<ClaimsTransformation Id="GetDomainFromEmail" TransformationMethod="ParseDomain">
<InputClaims>
<InputClaim ClaimTypeReferenceId="email" TransformationClaimType="emailAddress" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="domain" TransformationClaimType="domain" />
</OutputClaims>
</ClaimsTransformation>
<ClaimsTransformation Id="LookupDomain" TransformationMethod="LookupValue">
<InputClaims>
<InputClaim ClaimTypeReferenceId="domain" TransformationClaimType="inputParameterId" />
</InputClaims>
<InputParameters>
<InputParameter Id="wintellect.com" DataType="string" Value="valid" />
<InputParameter Id="microsoft.com" DataType="string" Value="valid" />
<InputParameter Id="test.com" DataType="string" Value="valid" />
<InputParameter Id="errorOnFailedLookup" DataType="boolean" Value="true" />
</InputParameters>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="domainStatus" TransformationClaimType="outputClaim" />
</OutputClaims>
</ClaimsTransformation>
But could not upload this policy and got this error:
Validation failed: 1 validation error(s) found in policy "B2C_1A_SIGNUP_SIGNIN" of tenant "<yor-tenant-id>.onmicrosoft.com".Invalid technical profile with id "Common-AAD" only the protocol handler ""Web.TPEngine.Providers.SelfAssertedAttributeProvider"" can have a ValidationTechnicalProfile.Invalid technical profile with id "Common-AAD" only the protocol handler ""Web.TPEngine.Providers.SelfAssertedAttributeProvider"" can have a ValidationTechnicalProfile.
Any help on how to verify domain in Microsoft SSO would be highly appreciated.
Thank you.
EDIT:
The technical profile is as follows:
<TechnicalProfile Id="Common-AAD">
<DisplayName>Microsoft Account or Microsoft-Connected Account</DisplayName>
<Protocol Name="OpenIdConnect" />
<OutputTokenFormat>JWT</OutputTokenFormat>
<Metadata>
<Item Key="authorization_endpoint">https://login.microsoftonline.com/common/oauth2/v2.0/authorize</Item>
<Item Key="client_id">my-client-id</Item>
<Item Key="DiscoverMetadataByTokenIssuer">true</Item>
<Item Key="HttpBinding">POST</Item>
<Item Key="IdTokenAudience">my-id</Item>
<Item Key="response_types">id_token</Item>
<Item Key="scope">openid profile email offline_access</Item>
<Item Key="UsePolicyInRedirectUri">false</Item>
<Item Key="ValidTokenIssuerPrefixes">https://login.microsoftonline.com/,https://sts.windows.net/</Item>
<Item Key="METADATA">https://login.microsoftonline.com/common/.well-known/openid-configuration</Item>
</Metadata>
<CryptographicKeys>
<!-- Make sure to update the reference ID of the client secret below you just created (B2C_1A_AADAppSecret) -->
<Key Id="client_secret" StorageReferenceId="B2C_1A_AppSecret" />
</CryptographicKeys>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="socialIdpAuthentication" />
<OutputClaim ClaimTypeReferenceId="identityProvider" PartnerClaimType="iss" />
<OutputClaim ClaimTypeReferenceId="issuerUserId" PartnerClaimType="sub" />
<OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="name" />
<OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="given_name" />
<OutputClaim ClaimTypeReferenceId="surName" PartnerClaimType="family_name" />
<OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="preferred_username" />
<OutputClaim ClaimTypeReferenceId="otherMails" />
<OutputClaim ClaimTypeReferenceId="signInName" />
<OutputClaim ClaimTypeReferenceId="signInNames.emailAddress" />
</OutputClaims>
<OutputClaimsTransformations>
<OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName" />
<OutputClaimsTransformation ReferenceId="CreateUserPrincipalName" />
<OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId" />
<OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromAlternativeSecurityId" />
</OutputClaimsTransformations>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-SocialLogin" />
</TechnicalProfile>

Azure AD B2C Linkedin claims provider

I am implementing the Linkedin sign-up/sign-in via custom policies but when I click on the LinkedinExchange button, I get the following exception from the User Journey Player:
An exception was caught when making a request to URL "https://api.linkedin.com/v1/people/~:(id,first-name,last-name,formatted-name,email-address)" using method "Get". The exception status code was "ProtocolError" with the following message: The remote server returned an error: (401) Unauthorized..
The remote server returned an error: (401) Unauthorized.
Here is the ClaimsProvider for Linkedin I added:
<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="AccessTokenResponseFormat">json</Item>
<Item Key="ClaimsEndpoint">https://api.linkedin.com/v1/people/~:(id,first-name,last-name,formatted-name,email-address)?format=json</Item>
<Item Key="HttpBinding">POST</Item>
<Item Key="UsePolicyInRedirectUri">0</Item>
<Item Key="client_id">XXXXXXXXXXXX</Item>
</Metadata>
<CryptographicKeys>
<Key Id="client_secret" StorageReferenceId="B2C_1A_LinkedinSecret" />
</CryptographicKeys>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="socialIdpUserId" PartnerClaimType="id" />
<OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="emailAddress" />
<OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="firstName" />
<OutputClaim ClaimTypeReferenceId="surname" PartnerClaimType="lastName" />
<OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="formattedName" />
<OutputClaim ClaimTypeReferenceId="identityProvider" DefaultValue="Linkedin" />
<OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="Linkedin" />
</OutputClaims>
<OutputClaimsTransformations>
<OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName" />
<OutputClaimsTransformation ReferenceId="CreateUserPrincipalName" />
<OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId" />
<OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromAlternativeSecurityId" />
</OutputClaimsTransformations>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-SocialLogin" />
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>
Does someone see what I am doing wrong ?
In order to add LinkedIn as an Identity Provider in Azure AD B2C via custom policies, make sure you have the following entry in the ClaimsProvider's <Metadata> section:
<Item Key="ClaimsEndpointAccessTokenName">oauth2_access_token</Ite‌​m>

Resources