You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Azure AD/Entra身份验证:角色声明未同步至主体

解决Azure AD角色声明未同步到HttpContext.User的问题

问题根源

Azure AD返回的应用角色声明默认使用"roles"作为声明类型,而你的授权策略中依赖的是标准ClaimTypes.Role(对应URI:http://schemas.microsoft.com/ws/2008/06/identity/claims/role),两者类型不匹配导致授权校验失败;同时若未显式配置声明映射,登录后角色声明可能无法被正确持久化到用户主体中。

解决方案

方案1:映射Azure AD角色到标准Role类型

在OIDC配置中添加声明映射,将Azure AD返回的"roles"声明转换为标准ClaimTypes.Role类型,确保授权策略能匹配到:

services.AddAuthentication()
    .AddMicrosoftIdentityWebApp(
        configuration.GetSection("AzureAd"),
        openIdConnectScheme: "MySchemeName",
        cookieScheme: null,
        displayName: "MySchemeName")
    .ConfigureOpenIdConnect(options =>
    {
        // 将Azure AD的"roles"声明映射到标准Role类型
        options.ClaimActions.MapUniqueJsonKey(ClaimTypes.Role, "roles");
    });

方案2:调整授权策略匹配原生声明类型

如果不需要依赖标准Role类型,直接修改授权策略使用Azure AD原生的"roles"声明类型:

options.AddPolicy("MyPolicy", policy =>
{
    policy.RequireAuthenticatedUser();
    // 使用Azure AD返回的原始声明类型"roles"
    policy.RequireClaim("roles", "AzureAppRoleName");
});

方案3:登录时手动保留角色声明

若使用自定义登录逻辑,在ExternalLoginCallback中确保将外部主体的角色声明复制到本地用户身份:

var externalLoginInfo = await _signInManager.GetExternalLoginInfoAsync();
if (externalLoginInfo != null)
{
    // 获取外部主体的角色声明
    var roleClaims = externalLoginInfo.Principal.FindAll("roles");
    
    // 创建本地身份并添加角色声明
    var identity = new ClaimsIdentity(externalLoginInfo.Principal.Identity);
    identity.AddClaims(roleClaims);
    
    // 登录用户,确保身份包含角色声明
    await _signInManager.SignInAsync(await _userManager.GetUserAsync(externalLoginInfo.Principal), isPersistent: false, "MySchemeName");
}

验证步骤

  1. 在自定义中间件中打印HttpContext.User.Claims的所有声明类型和值,确认角色声明已存在且类型与授权策略匹配。
  2. 重启应用后访问受保护页面,验证授权策略是否正常生效。

内容的提问来源于stack exchange,提问作者David Masters

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 14:31:12