Azure AD B2C - Custom Provider for GitHub cannot g

2019-08-13 17:28发布

问题:

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?

回答1:

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>