扩展基于角色的授权时遇到的问题



当我试图使用Microsoft身份扩展基于角色的授权时,遇到了一些问题。

当调用login操作方法时,如果没有将角色添加到声明列表中,它将生成令牌。

var claims = new List<Claim>
{
new Claim(ClaimTypes.Name,user.UserName),
new Claim(ClaimTypes.NameIdentifier,user.Id.ToString())
};
var roles = await _userManager.GetRolesAsync(user);  // If remove this await call then it work fine.
foreach (var role in roles)
{
claims.Add(new Claim(ClaimTypes.Role, role));
}

在生成令牌时将新角色添加到Claims中,几分钟后我确实收到了服务器的任何响应,它将显示如下错误。

错误为:调用的目标引发了异常。

在ConfigureServices方法下的Startup.cs类中。

services.AddDbContext<DataContext>(x => x.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
IdentityBuilder builder = services.AddIdentityCore<User>(opt =>
{
opt.Password.RequireDigit = false;
opt.Password.RequiredLength = 4;
opt.Password.RequireNonAlphanumeric = false;
opt.Password.RequireUppercase = false;
});
builder = new IdentityBuilder(builder.UserType, typeof(Role), builder.Services);
builder.AddEntityFrameworkStores<DataContext>();
builder.AddRoleValidator<RoleValidator<Role>>();
builder.AddRoleManager<RoleManager<Role>>();
builder.AddSignInManager<SignInManager<User>>();
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(auth =>
{
auth.TokenValidationParameters = new TokenValidationParameters()
{
// ValidateIssuer = true,
// ValidIssuer = Configuration["AuthSettings:Issuer"],
// ValidateAudience = true,
// ValidAudience = Configuration["AuthSettings:Audience"],
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration["AuthSettings:Key"])),
ValidateIssuer = false,
ValidateAudience = false
};
});
services.AddControllers(opt =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
opt.Filters.Add(new AuthorizeFilter(policy));
})
.AddNewtonsoftJson(options =>
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);

在AuthController 中

[HttpPost("login")]
public async Task<IActionResult> Login(UserForLoginDto loginDto)
{
var user = await _userManager.FindByNameAsync(loginDto.Username);
var result = await _signInManager.CheckPasswordSignInAsync(user, loginDto.Password, false);
if (result.Succeeded)
{
var appUsers = await _userManager.Users.Include(e => e.Photos)
.FirstOrDefaultAsync(next => next.NormalizedUserName == loginDto.Username.ToUpper());
var userToReturn = _mapper.Map<UserForListDto>(appUsers);
return Ok(new
{
token = GeneratejwtToken(appUsers),
user = userToReturn
});
}
else
{
return Unauthorized();
}

}
private async Task<string> GeneratejwtToken(User user)
{
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name,user.UserName),
new Claim(ClaimTypes.NameIdentifier,user.Id.ToString())
};
var roles = await _userManager.GetRolesAsync(user);
foreach (var role in roles)
{
claims.Add(new Claim(ClaimTypes.Role, role));
}
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["AuthSettings:Key"]));
var signingCredentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha512Signature);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(claims),
Expires = DateTime.Now.AddDays(1),
SigningCredentials = signingCredentials
};
var TokenHandler = new JwtSecurityTokenHandler();
var token = TokenHandler.CreateToken(tokenDescriptor);
return TokenHandler.WriteToken(token);
}

我解决了这个问题,在调用GeneratejwtToken方法时,我忘记了使用await关键字,因为该方法是异步方法。

token = await GeneratejwtToken(appUsers)

最新更新