本地与Azure App Service中Azure AD令牌声明差异问题
核心原因:身份认证中间件的声明映射规则差异
本地测试和Azure App Service部署环境的声明格式差异,本质是不同认证流程下,中间件对JWT声明的处理逻辑不同:
1. 本地测试环境:自动映射OIDC短声明到WS-Federation长URI
本地开发时,你使用的.NET身份认证中间件(比如Microsoft.Identity.Web或AzureAD.UI)默认开启了声明映射功能。这个功能会把Azure AD返回的OIDC标准短名称声明(如given_name、roles)自动转换成传统WS-Federation协议的长格式URI声明(对应ClaimTypes.GivenName、ClaimTypes.Role的取值)。这是为了兼容.NET早期依赖WS-Federation声明格式的身份系统。
2. Azure App Service环境:直接返回原始OIDC声明
当应用部署到Azure App Service并启用**内置身份验证(Easy Auth)**后,Easy Auth会直接转发Azure AD签发的原始ID Token,不会对声明名称做任何映射转换。Azure AD签发的ID Token遵循OIDC标准,所有声明都是短名称格式,所以你拿到的user.Claims里都是given_name、roles这类短键。
验证与统一解决方案
验证方法
分别在本地和Azure环境中输出并解码身份令牌:
- 本地:解码后会看到原始OIDC短声明,但中间件已经将其映射成长URI声明添加到
ClaimsPrincipal中 - Azure:解码后直接看到短名称声明,与
ClaimsPrincipal中的一致
统一处理方案
为了消除环境差异,推荐统一使用OIDC标准短名称获取声明,同时可以在中间件配置中强制关闭声明映射,让本地环境也使用短名称:
// 在Program.cs中配置身份认证时关闭声明映射 builder.Services.Configure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme, options => { // 禁用入站声明映射,直接使用原始OIDC声明名称 options.MapInboundClaims = false; });
或者使用Microsoft.Identity.Web的配置方式:
builder.Services.AddMicrosoftIdentityWebAppAuthentication(builder.Configuration) .Configure(options => { options.MapInboundClaims = false; });
这样无论本地还是Azure环境,都可以用user.FindFirst("given_name")?.Value统一获取声明值,避免环境差异问题。
内容的提问来源于stack exchange,提问作者Marty

