Xamarin应用经Azure AD认证调用下游Web API报未授权错误
Xamarin调用Azure AD保护的下游API返回401未授权解决方案
问题本质
下游API的JWT认证中间件没有成功校验Xamarin请求携带的Bearer令牌,导致HttpContext.User未被填充为已认证身份,触发匿名用户拒绝规则返回401。
分步排查修复
1. 先排查Xamarin端传参低级错误
- 检查令牌传值逻辑:
AcquireTokenInteractive执行后返回的authResult对象中,访问令牌存于authResult.AccessToken属性,确认你传入请求头的authToken变量确实取的是该属性值,没有误传ID令牌、空值或者Web应用端的缓存令牌。 - 确认请求头格式正确:
Authorization头值必须是Bearer {实际令牌},Bearer和令牌之间保留一个空格,没有多余换行、特殊字符。
2. 修复下游Web API的认证配置
你的Web应用能正常访问API是因为走的是机密客户端流,Xamarin作为公共客户端需要API端正确配置JWT校验规则:
- 确保API的服务注册逻辑使用Web API专属的认证方法,不要误用Web应用的认证配置,正确代码如下:
// Program.cs中注册服务 using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.Identity.Web; builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd")); // 补充令牌校验参数,匹配公共客户端令牌格式 builder.Services.Configure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme, options => { options.TokenValidationParameters.NameClaimType = "name"; options.TokenValidationParameters.RoleClaimType = "roles"; // 必须开启受众校验,确认受众和令牌aud字段匹配 options.TokenValidationParameters.ValidateAudience = true; }); // 中间件管道顺序不能错,*必须在Authorization之前调用Authentication* app.UseAuthentication(); app.UseAuthorization();
- 核对配置文件中
AzureAd节点的参数:Instance填你使用的Azure云登录端点,比如全球版是https://login.microsoftonline.com/TenantId填你实际的租户ID,和Xamarin端配置的租户ID保持一致ClientId填下游API对应的应用注册(服务端)的客户端ID,不要填成Xamarin客户端或者前端Web应用的客户端ID
3. 核对Azure AD应用注册配置
- 下游API的应用注册配置:
- 「公开API」板块中,确认应用ID URI格式正确(比如
api://xxxx,和你Xamarin请求令牌用的资源URI一致) - 已添加正确的委托权限,且已将Xamarin客户端的客户端ID加入授权的客户端列表
- 「公开API」板块中,确认应用ID URI格式正确(比如
- Xamarin客户端的应用注册配置:
- 「API权限」板块中,已经添加下游API的委托权限,且完成了管理员同意(如果是组织内租户)
- 确认你请求令牌时使用的scope正确:公共客户端交互式获取令牌时,不要直接混用Web应用用的
api://xxxx/.default,要明确填写你在API暴露板块添加的委托权限值,比如api://xxxx/Api.Access;如果用.default,要确保已经给Xamarin客户端提前授予了对应API的所有委托权限。
4. 排除App Service认证中间件干扰
如果你给下游API或者前置Web应用开了App Service自带的Easy Auth(应用服务认证):
- 不要将Easy Auth配置为「请求未经过身份验证时采取的操作=使用Azure AD登录」,这会在ASP.NET Core认证中间件运行前拦截请求,导致你自己的认证逻辑拿不到正确的用户身份
- 要么关闭Easy Auth完全用应用内的Microsoft.Identity.Web做认证,要么将Easy Auth配置为「允许匿名请求(无操作)」,由应用代码处理认证逻辑。
5. 快速校验令牌有效性
拿到Xamarin端获取到的访问令牌,本地解码后核对核心字段:
aud(受众):必须和下游API配置的ClientId或者应用ID URI完全一致iss(颁发者):必须和你使用的Azure AD端点、租户ID匹配scp(范围):必须包含你为下游API配置的委托权限,不能只包含Microsoft Graph的权限exp(过期时间):令牌未过期,时间戳和当前UTC时间匹配
内容的提问来源于stack exchange,提问作者javacavaj
相关产品推荐
相关产品推荐

