You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Azure AD B2C返回本地账户Access Token以调用MS Graph

解决方案:让Azure AD B2C返回本地账户可用的MS Graph访问令牌

核心思路

本地账户没有外部身份提供商的访问令牌,无法复用联合AAD账户的idp_access_token方案。需要让B2C作为客户端,代表用户获取MS Graph的委派访问令牌,并将其作为声明返回给你的ASP.NET应用。

步骤1:配置B2C应用的MS Graph权限

  1. 在B2C租户的Azure AD注册中,找到对应策略的应用(或新建专用应用)
  2. 添加Microsoft Graph的委派权限,按需选择:
    • User.ReadWrite:用于编辑用户姓名、手机号等基础信息
    • Directory.AccessAsUser.All:如需更高级的用户管理操作
  3. 完成管理员权限同意

步骤2:修改自定义策略,添加Graph令牌获取逻辑

2.1 新增ClaimsProvider与技术配置文件

在自定义策略的<ClaimsProviders>节点下插入:

<ClaimsProvider>
  <DisplayName>Microsoft Graph</DisplayName>
  <TechnicalProfiles>
    <TechnicalProfile Id="MSGraph-GetAccessToken">
      <DisplayName>Microsoft Graph Access Token</DisplayName>
      <Protocol Name="OAuth2" />
      <Metadata>
        <Item Key="AuthorizationEndpoint">{Settings:TenantId}/oauth2/v2.0/token</Item>
        <Item Key="HttpBinding">POST</Item>
        <Item Key="UsePolicyInRedirectUri">false</Item>
        <Item Key="ClientId">{Settings:GraphClientId}</Item>
        <Item Key="ClientSecret">{Settings:GraphClientSecret}</Item>
        <Item Key="GrantType">authorization_code</Item>
        <Item Key="Scope">https://graph.microsoft.com/User.ReadWrite</Item>
        <Item Key="ResponseErrorCode">invalid_grant</Item>
        <Item Key="ResponseErrorPattern">AADB2C90085</Item>
      </Metadata>
      <InputClaims>
        <InputClaim ClaimTypeReferenceId="authorization_code" PartnerClaimType="code" />
        <InputClaim ClaimTypeReferenceId="redirect_uri" PartnerClaimType="redirect_uri" />
      </InputClaims>
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="graph_access_token" PartnerClaimType="access_token" />
      </OutputClaims>
      <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
    </TechnicalProfile>
  </TechnicalProfiles>
</ClaimsProvider>

2.2 集成到用户旅程

在登录/注册用户旅程的<OrchestrationSteps>中,添加调用该技术配置文件的步骤(放在用户认证完成后的节点):

<OrchestrationStep Order="X" Type="ClaimsExchange">
  <ClaimsExchanges>
    <ClaimsExchange Id="GetGraphToken" TechnicalProfileReferenceId="MSGraph-GetAccessToken" />
  </ClaimsExchanges>
</OrchestrationStep>

2.3 声明类型与令牌输出配置

在<BuildingBlocks>/<ClaimsSchema>中添加声明定义:

<ClaimType Id="graph_access_token">
  <DisplayName>Microsoft Graph Access Token</DisplayName>
  <DataType>string</DataType>
  <AdminHelpText>Access token for Microsoft Graph</AdminHelpText>
</ClaimType>

在<RelyingParty>/<OutputClaims>中添加输出声明:

<OutputClaim ClaimTypeReferenceId="graph_access_token" />

步骤3:ASP.NET(.NET Framework)中使用令牌

从B2C返回的令牌中提取graph_access_token,调用MS Graph接口:

// 从ClaimsPrincipal中获取Graph令牌
var graphToken = User.Claims.FirstOrDefault(c => c.Type == "graph_access_token")?.Value;
if (!string.IsNullOrEmpty(graphToken))
{
    var graphClient = new GraphServiceClient(
        new DelegateAuthenticationProvider(requestMessage =>
        {
            requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", graphToken);
            return Task.CompletedTask;
        })
    );

    // 示例:更新用户名字
    var user = await graphClient.Me.Request().GetAsync();
    user.GivenName = "新的名字";
    await graphClient.Me.Request().UpdateAsync(user);
}

统一联合账户与本地账户的处理逻辑

通过identityProvider声明区分账户类型,分别使用对应令牌:

var identityProvider = User.Claims.FirstOrDefault(c => c.Type == "identityProvider")?.Value;
string accessToken;

if (identityProvider == "AzureAD") // 联合AAD账户
{
    accessToken = User.Claims.FirstOrDefault(c => c.Type == "idp_access_token")?.Value;
    // 使用只读权限调用Graph
}
else // 本地账户
{
    accessToken = User.Claims.FirstOrDefault(c => c.Type == "graph_access_token")?.Value;
    // 使用读写权限调用Graph
}

内容的提问来源于stack exchange,提问作者Sen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 17:25:51