Azure B2C技术咨询:无API认证与MSAL调用Graph API问题
嘿,很高兴看到你已经在Azure B2C上跑通了MSAL的示例应用,我来帮你拆解这两个问题:
问题1:能否在不依赖API的情况下运行该MSAL示例?
当然可以!用户认证流程本身完全不强制依赖Web服务,示例里绑定API只是为了演示“获取API访问令牌”的附加场景。你只需要调整几个关键配置,移除API相关依赖即可:
- 首先修改
Startup类里的Scopes数组,删掉API读写权限的范围,只保留OpenID Connect的基础身份范围:public static string[] Scopes = new string[] { OpenIdConnectScopes.OpenId, OpenIdConnectScopes.Profile }; - 然后调整
OpenIdConnectAuthenticationOptions中的Scope属性,同步改为基础范围:Scope = $"{OpenIdConnectScopes.OpenId} {OpenIdConnectScopes.Profile}" - 最后简化
OnAuthorizationCodeReceived方法:因为现在不需要获取API的访问令牌,只需要完成用户身份认证即可。你可以修改令牌请求的范围,或者如果只需要ID Token的话,甚至可以把ResponseType设置为OpenIdConnectResponseTypes.IdToken(跳过Authorization Code的令牌交换步骤):private async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedNotification notification) { string signedInUserID = notification.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value; TokenCache userTokenCache = new MSALSessionCache(signedInUserID, notification.OwinContext.Environment["System.Web.HttpContextBase"] as HttpContextBase).GetMsalCacheInstance(); ConfidentialClientApplication cca = new ConfidentialClientApplication(ClientId, Authority, RedirectUri, new ClientCredential(ClientSecret), userTokenCache, null); // 只请求基础身份范围的令牌 AuthenticationResult result = await cca.AcquireTokenByAuthorizationCodeAsync(code, new string[] { OpenIdConnectScopes.OpenId, OpenIdConnectScopes.Profile }); }
总结一下:认证的核心是验证用户身份、获取ID Token,调用API只是可选的延伸场景,所以完全可以脱离API独立运行示例。
问题2:使用MSAL调用Graph API时遇到的AADB2C90068错误
这个错误的核心原因是你用了B2C的Policy端点来请求Graph API的令牌——Graph API是Azure AD的服务,不是B2C专属服务,所以必须切换到正确的认证端点并调整配置:
调整Authority配置:
原来的Authority是基于B2C Policy生成的(比如https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}),现在调用Graph API需要改用Azure AD的V2通用端点:// Tenant可以是你的B2C租户域名(比如yourtenant.onmicrosoft.com)或租户ID public static string GraphAuthority = $"https://login.microsoftonline.com/{Tenant}/v2.0";配置正确的Graph API权限:
在Azure门户的B2C租户应用注册中,添加Microsoft Graph的权限(不要选自己的API):- 如果是用户上下文调用,添加
Delegated权限(比如User.Read) - 如果是后台服务调用,添加
Application权限(比如Directory.Read.All)
注意:添加Application权限后,必须点击“授予管理员同意”才能生效。
- 如果是用户上下文调用,添加
修改MSAL调用逻辑:
调用Graph API时,要单独创建使用Graph Authority的ConfidentialClientApplication实例,并指定Graph的权限范围:// Graph API的权限范围,示例为读取当前用户信息 string[] graphScopes = new string[] { "https://graph.microsoft.com/User.Read" }; // 使用Graph专属的Authority创建CCA ConfidentialClientApplication graphCca = new ConfidentialClientApplication(ClientId, GraphAuthority, RedirectUri, new ClientCredential(ClientSecret), userTokenCache, null); AuthenticationResult graphResult = await graphCca.AcquireTokenByAuthorizationCodeAsync(code, graphScopes); // 使用graphResult.AccessToken调用Graph API接口
另外你提到“并非B2C门户创建应用”——其实在Azure门户的B2C租户下的应用注册是正确的,问题出在调用Graph时误用了B2C的Policy端点,切换到Azure AD通用端点就能解决这个错误。
内容的提问来源于stack exchange,提问作者Green_qaue

