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

SamD 151 Reputation points
2020-08-26T07:40:32.273+00:00

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 policies we were able to fetch access_token. However, we cannot fetch the refresh_token.

This is how ClaimsSchema is defined in TrustFrameworkExtensions.xml :

20439-screenshot-2020-08-26-at-130458.png

Also in the same file, under the TechnicalProfile of Microsoft login, following OutputClaims node is added (some child nodes are removed for clarity):

20347-screenshot-2020-08-26-at-130701.png

Then under the relevant RelyingParty node following OutputClaims node is added (some child nodes are removed for clarity):

20440-screenshot-2020-08-26-at-130821.png

According to documentation there is no claim resolver for refresh_token.

Any suggestion to get this work?

Active Directory Federation Services
Active Directory Federation Services
An Active Directory technology that provides single-sign-on functionality by securely sharing digital identity and entitlement rights across security and enterprise boundaries.
1,198 questions
Microsoft Entra External ID
Microsoft Entra External ID
A modern identity solution for securing access to customer, citizen and partner-facing apps and services. It is the converged platform of Azure AD External Identities B2B and B2C. Replaces Azure Active Directory External Identities.
2,654 questions
0 comments No comments
{count} votes

Accepted answer
  1. AmanpreetSingh-MSFT 56,311 Reputation points
    2020-08-26T14:29:48.82+00:00

    Hello @SampathDilhan-7447

    To get both Access and Refresh tokens, you would need to federate MSA IDP via OAuth with B2C. As of now, for OIDC IDPs only Access Token is passed through.

    Please refer to below Technical Profile to add MSA IDP using OAuth:

    • Define Claim: <ClaimType Id="ms_access_token">
      <DisplayName>MS access token</DisplayName>
      <DataType>string</DataType>
      <UserHelpText>access token form 3rd party MS AD. </UserHelpText>
      </ClaimType>
      <ClaimType Id="ms_refresh_token">
      <DisplayName>MS Refresh token</DisplayName>
      <DataType>string</DataType>
      <UserHelpText>refresh token form 3rd party MS AD. </UserHelpText>
      </ClaimType>
    • Define Technical Profile: <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">XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX</Item>
      <Item Key="HttpBinding">POST</Item>
      <Item Key="scope">user.read offline_access</Item>
      <Item Key="UsePolicyInRedirectUri">0</Item>
      </Metadata>
      <CryptographicKeys>
      <Key Id="client_secret" StorageReferenceId="B2C_1A_MSASecret"/>
      </CryptographicKeys>
      <OutputClaims>
      <OutputClaim ClaimTypeReferenceId="identityProvider" DefaultValue="live.com" />
      <OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="socialIdpAuthentication" />
      <OutputClaim ClaimTypeReferenceId="socialIdpUserId" 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>

    This will return both Access and Refresh tokens, as highlighted below:
    20623-image.png

    -----------------------------------------------------------------------------------------------------------

    Please "Accept the answer" if the information helped you. This will help us and others in the community as well.

    1 person found this answer helpful.

1 additional answer

Sort by: Most helpful
  1. Alok Aswal 1 Reputation point
    2023-09-19T08:35:48.73+00:00

    Hi @AmanpreetSingh-MSFT

    I'm using Key cloak as third party IDP and azure b2c as federated server, I tried same as described above, but getting error.

    AADB2C90289: We encountered an error connecting to the identity provider. Please try again later.

    Below is technical profile for key cloak.

    <ClaimsProvider>
          <DisplayName>Azureb2c Qa India</DisplayName>
          <TechnicalProfiles>
            <TechnicalProfile Id="IDP">
              <DisplayName>External IDP</DisplayName>
                 
            <Protocol Name="OAuth2"/>
            <OutputTokenFormat>JWT</OutputTokenFormat>
              <Metadata>
                <Item Key="AccessTokenEndpoint">https://servername.com/auth/realms/realemName/protocol/openid-connect/token</Item>
                <Item Key="authorization_endpoint">https://servername.com/auth/realms/realemName/protocol/openid-connect/auth</Item>
                <Item Key="ClaimsEndpoint">https://servername.com/auth/realms/realemName/protocol/openid-connect/userinfo</Item>
                <Item Key="ClaimsEndpointAccessTokenName">access_token</Item>
                <Item Key="response_types">code</Item>
                <Item Key="BearerTokenTransmissionMethod">AuthorizationHeader</Item>
                <Item Key="client_id">clientid</Item>
                <Item Key="HttpBinding">POST</Item>
                <Item Key="scope">openid offline_access</Item>
                <Item Key="UsePolicyInRedirectUri">0</Item>
          </Metadata>
              <CryptographicKeys>
                <Key Id="client_secret" StorageReferenceId="B2C_1A_ClientSecret" />   
              </CryptographicKeys>
              <OutputClaims>
                <OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="socialIdpAuthentication" />
                <OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="given_name" />
                <OutputClaim ClaimTypeReferenceId="surname" PartnerClaimType="family_name" />
                <OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="name" />
                <OutputClaim ClaimTypeReferenceId="userName" PartnerClaimType="preferred_username" />
                <OutputClaim ClaimTypeReferenceId="identityProvider" PartnerClaimType="iss" />
                <OutputClaim ClaimTypeReferenceId="issuerUserId" PartnerClaimType="sub" />
                <OutputClaim ClaimTypeReferenceId="userId" PartnerClaimType="userid" />
                <OutputClaim ClaimTypeReferenceId="externalIdToken" PartnerClaimType="{oauth2:refresh_token}" />
                <OutputClaim ClaimTypeReferenceId="accessToken" PartnerClaimType="{oauth2:access_token}" /> 
     <OutputClaim ClaimTypeReferenceId="dealerCode" PartnerClaimType="dealercode" /> 
              </OutputClaims>
              <OutputClaimsTransformations>
                <OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName" />
                <OutputClaimsTransformation ReferenceId="CreateUserPrincipalName" />
                <OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId" />
                <OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromAlternativeSecurityId" />
              </OutputClaimsTransformations>
              <UseTechnicalProfileForSessionManagement ReferenceId="SM-SocialLogin" />
            </TechnicalProfile>
          </TechnicalProfiles>
        </ClaimsProvider>
    

    can you suggest how to make it work, for OAuth2 the urls should be same as OpenId protocol or different.

    0 comments No comments