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

Posted

技术标签:

【中文标题】在 Azure B2C 中获取刷新令牌,Azure AD App 是第三方 IDP【英文标题】:Getting Refresh Token in Azure B2C, with Azure AD App being the third party IDP 【发布时间】:2021-07-04 08:53:06 【问题描述】:

我们有一个 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没有。

我还需要进行哪些更改才能获得刷新令牌?

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

【参考方案2】:

事实证明,您需要将 Technical Profile 的协议从“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>

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

【讨论】:

以上是关于在 Azure B2C 中获取刷新令牌,Azure AD App 是第三方 IDP的主要内容,如果未能解决你的问题,请参考以下文章

保护 Azure Active Directory B2C 访问令牌和刷新令牌

Azure AD B2C OpenID Connect 刷新令牌

Azure AD B2C 刷新令牌/ID 令牌 iOS Swift 4

刷新 id_token 时,Azure AD B2C 似乎在创建“未知”用户?

是否可以强制禁用 Azure AD B2c 中的访问令牌?

在 Postman 中为 Azure AD B2C 请求访问令牌