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

为.NET Identity添加JWT后基于角色的授权失效问题

解决方案:.NET Identity与JWT共存时角色授权失败问题

问题根源

当你将JWT设为默认认证Scheme时,[Authorize(Roles = "Admin")]会默认使用JWT Scheme进行认证,忽略了Identity的Cookie认证。同时,若Identity生成的ClaimsPrincipal中缺少ClaimTypes.Role类型的角色声明,也会导致角色校验失败。

具体解决步骤

1. 确保Identity用户的角色声明正确注入

自定义AppClaimsPrincipalFactory,确保用户的角色被添加为标准的ClaimTypes.Role声明:

public class AppClaimsPrincipalFactory : UserClaimsPrincipalFactory<IdentityUser, IdentityRole>
{
    private readonly UserManager<IdentityUser> _userManager;

    public AppClaimsPrincipalFactory(UserManager<IdentityUser> userManager, RoleManager<IdentityRole> roleManager, IOptions<IdentityOptions> optionsAccessor)
        : base(userManager, roleManager, optionsAccessor)
    {
        _userManager = userManager;
    }

    protected override async Task<ClaimsIdentity> GenerateClaimsAsync(IdentityUser user)
    {
        var identity = await base.GenerateClaimsAsync(user);
        // 获取用户角色并添加为标准Role声明
        var roles = await _userManager.GetRolesAsync(user);
        foreach (var role in roles)
        {
            identity.AddClaim(new Claim(ClaimTypes.Role, role));
        }
        return identity;
    }
}

2. 调整授权策略(二选一即可)

方案A:直接在控制器中指定多认证Scheme

修改WeatherForecastController的Authorize属性,明确允许JWT和Identity Cookie两种认证方式:

[HttpGet, Authorize(AuthenticationSchemes = "Identity.Application,JwtBearer", Roles = "Admin")]
public IEnumerable<WeatherForecast> Get()
{
    // 方法逻辑不变
}

方案B:创建全局自定义授权策略

在启动类的授权配置中添加支持双Scheme的Admin专属策略:

builder.Services.AddAuthorization(options =>
{
    options.DefaultPolicy = new AuthorizationPolicyBuilder("Identity.Application", JwtBearerDefaults.AuthenticationScheme)
        .RequireAuthenticatedUser()
        .Build();

    // 添加Admin角色专属策略,支持两种认证方式
    options.AddPolicy("AdminAccess", policy =>
    {
        policy.AddAuthenticationSchemes("Identity.Application", JwtBearerDefaults.AuthenticationScheme);
        policy.RequireAuthenticatedUser();
        policy.RequireRole("Admin");
    });
});

然后在控制器中使用该策略:

[HttpGet, Authorize(Policy = "AdminAccess")]
public IEnumerable<WeatherForecast> Get()
{
    // 方法逻辑不变
}

3. 验证用户角色分配

确保测试用户确实被分配了Admin角色,可以通过以下代码确认:

// 在注册或用户管理逻辑中添加角色分配
var user = await _userManager.FindByNameAsync("你的测试用户名");
await _userManager.AddToRoleAsync(user, "Admin");

内容的提问来源于stack exchange,提问作者AJ Raj

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 22:55:17