Claim
- 一部分信息
- Name-Value
- 可以来自内部或外部
- 基于策略的(Policy)
Docs:Claims-based authorization in ASP.NET Core
UserController 中操作 Claim
User 与 Claim 的关系类似与 User 与 Role 的关系。
public async Task<IActionResult> ManageClaims(string id){var user = await _userManager.Users.Include(x => x.Claims).Where(x => x.Id == id).SingleOrDefaultAsync();if (user == null){return RedirectToAction("Index");}// 筛选出该 User 没有的 Claimvar leftClaims = ClaimTypes.AllClaimTypeList.Except(user.Claims.Select(x => x.ClaimType)).ToList();var vm = new ManageClaimsViewModel{UserId = id,AvailableClaims = leftClaims};return View(vm);}[HttpPost]public async Task<IActionResult> ManageClaims(ManageClaimsViewModel vm){var user = await _userManager.FindByIdAsync(vm.UserId);if (user == null){return RedirectToAction("Index");}var claim = new IdentityUserClaim<string>{ClaimType = vm.ClaimId,ClaimValue = vm.ClaimId};user.Claims.Add(claim);var result = await _userManager.UpdateAsync(user);if (result.Succeeded){return RedirectToAction("EditUser", new { id = vm.UserId });}ModelState.AddModelError(string.Empty, "编辑用户Claims时发生错误");return View(vm);}[HttpPost]public async Task<IActionResult> RemoveClaim(string id, string claim){var user = await _userManager.Users.Include(x => x.Claims).Where(x => x.Id == id).SingleOrDefaultAsync();if (user == null){return RedirectToAction("Index");}var claims = user.Claims.Where(x => x.ClaimType == claim).ToList();foreach (var c in claims){user.Claims.Remove(c);}var result = await _userManager.UpdateAsync(user);if (result.Succeeded){return RedirectToAction("EditUser", new { id });}ModelState.AddModelError(string.Empty, "编辑用户Claims时发生错误");return RedirectToAction("ManageClaims", new { id });}
Policy(策略)
- 注册 Policy
- 使用 Policy 进行授权
Docs:Policy-based authorization in ASP.NET Core
添加策略
通过 Role 和 Claim 添加策略:
services.AddAuthorization(options =>{options.AddPolicy("仅限管理员", policy => policy.RequireRole("Administrators"));options.AddPolicy("编辑专辑", policy=> policy.RequireClaim("Edit Albums"));});
两个注意事项
- 如果登录账号时抛出 No IUserTokenProvider is registered 异常,可以通过 AddDefaultTokenProviders() 解决
- 修改用户的 Claim 后,需重新登录才能生效。如果不想重新登录,可以通过 RefreshSignInAsync 解决
- PS:这会带来一些别的问题 Update user claims without updating authentication time

