配置Azure B2C的移动应用如何获取可被C# Web API验证的访问令牌
第一步:Azure B2C 门户侧配置调整
- 注册/配置Web API的应用注册:进入B2C租户的「应用注册」页面,为Web API新建独立的应用注册(无需配置重定向URI,纯后端服务不需要),进入该应用的「公开API」页,先设置「应用程序ID URI」,默认值
api://[该API应用的ClientId]即可,保存后添加自定义作用域,例如命名为access_as_user,同意权限选择「管理员和用户」,填写对应的显示名称与描述后启用该作用域。 - 为移动应用授予API权限:找到移动应用对应的应用注册,进入「API权限」页,点击「添加权限」,切换到「我的API」标签,选中上一步创建的Web API应用,勾选刚创建的
access_as_user权限后确认添加,随后点击「授予管理员同意」完成租户级授权,避免用户登录时重复弹出权限申请框。 - 检查用户流配置:进入
B2C_1_sign_up_sign_in用户流的配置页,在「应用程序声明」中勾选你需要API侧获取的字段(例如name、用户唯一标识oid等),避免后续令牌缺少必要声明。
第二步:C# Web API 配置修正
你当前的配置存在两处冗余/错误:一是纯Web API不需要AddMicrosoftIdentityWebAppAuthentication(该方法是为Web页面应用准备的),二是B2C的实例地址配置错误,普通AAD才用login.microsoftonline.com,B2C需要用租户专属的b2clogin.com域名。
首先修正appsettings.json配置,补充API专属的参数:
"AzureB2C": { "Instance": "https://[你的B2C租户名称].b2clogin.com/", "Domain": "[domain].onmicrosoft.com", "ClientId": "[Web API应用自身的ClientId,不要填移动应用的ClientId]", "TenantId": "[tenantId]", "SignUpSignInPolicyId": "B2C_1_sign_up_sign_in" }
再调整服务注册代码:
// 移除冗余的Web应用认证配置,只保留API认证 services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi( options => { Configuration.Bind("AzureB2C", options); options.TokenValidationParameters.NameClaimType = "name"; // 可选:显式开启受众校验,确保只有发给当前API的令牌能通过验证 options.TokenValidationParameters.ValidateAudience = true; options.TokenValidationParameters.ValidAudience = Configuration["AzureB2C:ClientId"]; }, options => { Configuration.Bind("AzureB2C", options); }); // 注意中间件顺序不能乱,必须先开启认证再开启授权 app.UseAuthentication(); app.UseAuthorization();
后续你需要保护的接口只要加上[Authorize]特性即可自动完成令牌校验,需要限制接口权限的话可以额外加[RequiredScope("access_as_user")]特性。
第三步:移动应用端获取有效Access Token
不需要修改现有登录流程,仅需要调整请求的scope参数即可:
- 将你之前获取ID Token时传入的scope列表,从默认的
openid profile offline_access [移动应用ClientId],新增Web API的完整作用域:api://[Web API应用的ClientId]/access_as_user - 走现有正常的B2C登录流程,成功后会同时返回ID Token、Refresh Token和可用于API访问的Access Token
- 调用Web API时,将Access Token填入请求头即可:
Authorization: Bearer <你获取到的Access Token> - 如果你用的是MSAL移动端SDK(MAUI/Xamarin的Microsoft.Identity.Client包),直接在
AcquireTokenInteractive或AcquireTokenSilent方法的参数中传入上述包含API scope的数组,就能直接拿到符合要求的Access Token。
内容的提问来源于stack exchange,提问作者Kevin
相关产品推荐
相关产品推荐

