如何让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权限
- 在B2C租户的Azure AD注册中,找到对应策略的应用(或新建专用应用)
- 添加Microsoft Graph的委派权限,按需选择:
User.ReadWrite:用于编辑用户姓名、手机号等基础信息Directory.AccessAsUser.All:如需更高级的用户管理操作
- 完成管理员权限同意
步骤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
相关产品推荐
相关产品推荐

