在Identity中如何在JWT令牌中携带用户角色及代码问题排查
问题修复方案
一、JWT角色不生效的修复
你当前代码的核心问题是:创建SecurityTokenDescriptor之后才往Claim列表添加角色,但Subject引用的是最初创建的ClaimsIdentity,后续列表的修改不会同步到已生成的ClaimsIdentity中,导致角色无法写入Token。
修改后的Authenticate方法:
public async Task<JwtFeildsDto> Authenticate(string UserName, string PasswordHash) { var user = await _userManager.FindByNameAsync(UserName); var roles = await _userManager.GetRolesAsync(user); var tokenExpireTimeStamp = DateTime.Now.AddHours(Constansts.JWT_TOKEN_EXPIRE_TIME); var jwtSecurityTokenHandler = new JwtSecurityTokenHandler(); var tokenKey = Encoding.ASCII.GetBytes(Constansts.JWT_SECURITY_KEY_FOR_TOKEN); // 先将所有Claim(含角色)添加到列表,再创建ClaimsIdentity var claimList = new List<Claim>() { new Claim("username", UserName), new Claim(ClaimTypes.PrimaryGroupSid,"User Group 01") }; // 提前添加角色到Claim列表 foreach (var item in roles) { claimList.Add(new Claim(ClaimTypes.Role, item)); } var securityTokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(claimList), // 用包含角色的列表创建ClaimsIdentity Expires = tokenExpireTimeStamp, SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(tokenKey),SecurityAlgorithms.HmacSha256Signature) }; var securityToken = jwtSecurityTokenHandler.CreateToken(securityTokenDescriptor); var token = jwtSecurityTokenHandler.WriteToken(securityToken); return new JwtFeildsDto { token = token, user_name = UserName, expire_time = (int)tokenExpireTimeStamp.Subtract(DateTime.Now).TotalSeconds }; }
二、JWTAuthorizationManager实例化问题修复
你的JWTAuthorizationManager构造函数依赖UserManager<User>,但Login方法中直接new JWTAuthorizationManager()未传参,会导致编译错误,同时违反依赖注入原则。
步骤1:注册服务到DI容器
在Program.cs(或Startup.cs)中注册JWTAuthorizationManager:
// .NET 6+ 写法 builder.Services.AddScoped<JWTAuthorizationManager>();
步骤2:通过构造函数注入使用
修改Controller代码,避免手动实例化:
// 你的Controller类 private readonly ILoginService _loginService; private readonly JWTAuthorizationManager _jwtAuthorizationManager; // 构造函数注入依赖 public YourController(ILoginService loginService, JWTAuthorizationManager jwtAuthorizationManager) { _loginService = loginService; _jwtAuthorizationManager = jwtAuthorizationManager; } [HttpPost] public async Task<IActionResult> Login([FromForm] string userName, string password, bool remmberMe) { if (ModelState.IsValid) { var result = await _loginService.UserLogin(userName, password, remmberMe); if (result == true) { // 使用注入的实例,注意加await调用异步方法 var loginResult = await _jwtAuthorizationManager.Authenticate(userName, password); return Ok(loginResult); } else { return Unauthorized(MessageLib.Message.unaAuthorized); } } return BadRequest(); }
额外验证
生成Token后,可通过JWT解码工具验证Payload中是否包含role字段,确认角色已正确写入。
内容的提问来源于stack exchange,提问作者sadegh
相关产品推荐
相关产品推荐

