在 Azure B2C 中获取刷新令牌,Azure AD App 是第三方 IDP

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

我们有一个 Web 应用程序,用户通过 Azure B2C 进行身份验证。我们添加了一个 Azure AD 应用作为声明提供者。所以我们的用户应该能够通过本地帐户和 Azure AD 帐户登录。对于通过 Azure AD 应用程序登录的用户,我们希望获得访问和刷新令牌,以便能够调用 Microsoft Graph。获取访问令牌有效,但未发送刷新令牌。

这是自定义策略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>

而 signup_signin.xml 看起来像这样:

<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>

在用户声明中,idp_access_token 中有访问令牌,但 idp_refresh_token 中没有访问令牌。

我还需要更改什么才能获得刷新令牌?

我去年看过这个,这是不可能的,因为只返回了访问令牌。

https://docs.microsoft.com/en-us/azure/active-directory-b2c/idp-pass-through-user-flow?pivots=b2c-custom-policy

原来您需要将技术配置文件的协议从“OpenIdConnect”切换到“OAuth2”并自行指定各种端点:

<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>

这样,刷新令牌最终出现在用户的声明中: