Azure AD B2C配置故障:React客户端调用.NET 5 API身份验证失败
解决React + Azure AD B2C + .NET5 Web API权限与受众验证问题
核心问题分析
所有问题本质都是令牌请求配置错误和API验证配置不匹配导致的,先从令牌缺少权限范围的问题入手解决,再处理API调用的错误。
问题1:令牌中缺少access_as_staff权限范围
这是因为令牌请求未正确指向API权限范围,或API权限配置未完成:
- 检查API应用注册的权限暴露
- 登录Azure门户,找到Portal API应用注册,进入「公开API」页面:
- 确认已设置应用ID URI(格式一般为
api://{API_CLIENT_ID}) - 确认已添加
access_as_staff这个Delegated权限范围,状态为「已启用」
- 确认已设置应用ID URI(格式一般为
- 登录Azure门户,找到Portal API应用注册,进入「公开API」页面:
- 检查客户端应用注册的权限授权
- 找到Portal Client应用注册,进入「API权限」页面:
- 确认已添加Portal API的
access_as_staff权限 - 点击「授予管理员同意」(必须完成此步骤,否则客户端无法获取对应权限的令牌)
- 确认已添加Portal API的
- 找到Portal Client应用注册,进入「API权限」页面:
- 修正React的MSAL令牌请求范围
- 请求令牌时必须使用API的完整权限范围格式,不能只写
access_as_staff,示例:const tokenRequest = { scopes: ["api://d1a138a9-2379-1111-1111-111111111111/access_as_staff"] }; const response = await msalInstance.acquireTokenSilent(tokenRequest); - 这里的
api://{API_CLIENT_ID}是API应用注册中设置的应用ID URI
- 请求令牌时必须使用API的完整权限范围格式,不能只写
问题2:API调用错误处理
错误1:IDW10201: Neither scope or roles claim was found in the bearer token.
- 原因:客户端和API混用同一个Client ID,导致获取的是客户端自身的令牌,而非针对API的令牌,这类令牌不会包含API的权限范围。
- 解决:
- API必须使用Portal API的Client ID,客户端使用Portal Client的Client ID,两者不能混用
- 确保客户端请求的是API的令牌(参考上述令牌请求范围配置)
错误2:IDX10214: Audience validation failed.
- 原因:客户端获取的令牌受众(
aud字段)是Portal Client的Client ID,但API验证的是Portal API的Client ID,两者不匹配。 - 解决:
- 修正React的MSAL令牌请求范围,确保请求的是API的完整权限范围(如上述示例),这样获取的Access Token的
aud字段才会是API的Client ID或应用ID URI - 确认.NET5 API的
AppSettings.json中AzureAdB2C配置的Audience是API的应用ID URI或Client ID,示例:"AzureAdB2C": { "Instance": "https://your-tenant.b2clogin.com/", "ClientId": "d1a138a9-2379-1111-1111-111111111111", "Domain": "your-tenant.onmicrosoft.com", "SignUpSignInPolicyId": "B2C_1_SignUpSignIn", "Audience": "api://d1a138a9-2379-1111-1111-111111111111" } - 确认API的Startup.cs中身份验证配置正确加载上述配置:
services.AddMicrosoftIdentityWebApi(Configuration, "AzureAdB2C");
- 修正React的MSAL令牌请求范围,确保请求的是API的完整权限范围(如上述示例),这样获取的Access Token的
验证步骤
- 获取令牌后,用JWT解码工具查看
scp字段是否包含access_as_staff,aud字段是否为API的Client ID或应用ID URI - 调用API时,确保请求头中的
Authorization是Bearer {你的Access Token},而非ID Token(response.idToken是身份令牌,不能用来调用API,必须用response.accessToken)
内容的提问来源于stack exchange,提问作者Ray
相关产品推荐
相关产品推荐

