Visual

16 角色管理.mp4 (108.39MB)

一句话的事儿

  • 在User的基础进行分类,
  • 对角色进行CRUD(增加,删除,更新,查询)

Role Manager

  • 创建,删除 Role
  • 把用户添加到 Role
  • 对 Role 进行授权 [Authorize(Roles = "xxxRle")]

要启用默认的 IdentityRole,在 Startup 里面配置时就不能使用 AddDefaultIdentity 了。需要使用 AddIdentity 并指定 User 和 Role:

  1. services.AddIdentity<ApplicationUser, IdentityRole>(options =>
  2. {
  3. options.Password.RequireNonAlphanumeric = false;
  4. ...
  5. })
  6. .AddDefaultUI(UIFramework.Bootstrap4)
  7. .AddEntityFrameworkStores<ApplicationDbContext>();

Role Controller

通过注入的 UserManager 和 RoleManager 操作角色。

单独操作 Role 的代码和 UserController 相似,主要不同在于修改 User 的 Role:

  1. using Heavy.Web.Models;
  2. using Heavy.Web.ViewModels;
  3. using Microsoft.AspNetCore.Authorization;
  4. using Microsoft.AspNetCore.Identity;
  5. using Microsoft.AspNetCore.Mvc;
  6. using Microsoft.EntityFrameworkCore;
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Linq;
  10. using System.Threading.Tasks;
  11. namespace Heavy.Web.Controllers
  12. {
  13. [Authorize]
  14. public class RoleController : Controller
  15. {
  16. private readonly UserManager<ApplicationUser> _userManager;
  17. private readonly RoleManager<IdentityRole> _roleManager;
  18. public RoleController(
  19. UserManager<ApplicationUser> userManager,
  20. RoleManager<IdentityRole> roleManager)
  21. {
  22. _userManager = userManager;
  23. _roleManager = roleManager;
  24. }
  25. /// <summary>
  26. /// 获取所有角色
  27. /// </summary>
  28. /// <returns></returns>
  29. public async Task<IActionResult> Index()
  30. {
  31. var roles = await _roleManager.Roles.ToListAsync();
  32. return View(roles);
  33. }
  34. public IActionResult AddRole()
  35. {
  36. return View();
  37. }
  38. /// <summary>
  39. /// 增加一个角色
  40. /// </summary>
  41. /// <param name="roleAddViewModel">新增角色的UI</param>
  42. /// <returns></returns>
  43. [HttpPost]
  44. public async Task<IActionResult> AddRole(RoleAddViewModel roleAddViewModel)
  45. {
  46. if (!ModelState.IsValid)
  47. {
  48. return View(roleAddViewModel);
  49. }
  50. var role = new IdentityRole { Name = roleAddViewModel.RoleName };
  51. var result = await _roleManager.CreateAsync(role);
  52. if (result.Succeeded)
  53. {
  54. return RedirectToAction("Index");
  55. }
  56. foreach (var error in result.Errors)
  57. {
  58. ModelState.AddModelError(string.Empty, error.Description);
  59. }
  60. return View(roleAddViewModel);
  61. }
  62. /// <summary>
  63. /// 编辑角色[HttpGet]
  64. /// </summary>
  65. /// <param name="id"></param>
  66. /// <returns></returns>
  67. public async Task<IActionResult> EditRole(string id)
  68. {
  69. var role = await _roleManager.FindByIdAsync(id);
  70. if (role == null)
  71. {
  72. return RedirectToAction("Index");
  73. }
  74. var roleEditViewModel = new RoleEditViewModel
  75. {
  76. Id = id,
  77. RoleName = role.Name,
  78. Users = new List<string>()
  79. };
  80. var users = await _userManager.Users.ToListAsync();
  81. foreach (var user in users)
  82. {
  83. if (await _userManager.IsInRoleAsync(user, role.Name))
  84. {
  85. roleEditViewModel.Users.Add(user.UserName);
  86. }
  87. }
  88. return View(roleEditViewModel);
  89. }
  90. /// <summary>
  91. /// 编辑角色[HttpPost]
  92. /// </summary>
  93. /// <param name="roleEditViewModel"></param>
  94. /// <returns></returns>
  95. [HttpPost]
  96. public async Task<IActionResult> EditRole(RoleEditViewModel roleEditViewModel)
  97. {
  98. var role = await _roleManager.FindByIdAsync(roleEditViewModel.Id);
  99. if (role != null)
  100. {
  101. role.Name = roleEditViewModel.RoleName;
  102. var result = await _roleManager.UpdateAsync(role);
  103. if (result.Succeeded)
  104. {
  105. RedirectToAction("Index");
  106. }
  107. ModelState.AddModelError(string.Empty, "更新角色时发生错误。");
  108. return View(roleEditViewModel);
  109. }
  110. return RedirectToAction("Index");
  111. }
  112. /// <summary>
  113. /// 删除某一角色
  114. /// </summary>
  115. /// <param name="id"></param>
  116. /// <returns></returns>
  117. public async Task<IActionResult> DeleteRole(string id)
  118. {
  119. var role = await _roleManager.FindByNameAsync(id);
  120. if (role != null)
  121. {
  122. var result = await _roleManager.DeleteAsync(role);
  123. if (result.Succeeded)
  124. {
  125. return RedirectToAction("Index");
  126. }
  127. ModelState.AddModelError(string.Empty, "删除角色发生错误");
  128. }
  129. ModelState.AddModelError(string.Empty, "未找到对应的角色");
  130. return View("Index", await _roleManager.Roles.ToListAsync());
  131. }
  132. /// <summary>
  133. /// 在角色中添加一个用户[HttpGet]
  134. /// </summary>
  135. /// <param name="roleId"></param>
  136. /// <returns></returns>
  137. public async Task<IActionResult> AddUserToRole(string roleId)
  138. {
  139. var role = await _roleManager.FindByIdAsync(roleId);
  140. if (role == null)
  141. {
  142. return RedirectToAction("Index");
  143. }
  144. var vm = new UserRoleViewModel { RoleId = role.Id };
  145. var users = await _userManager.Users.ToListAsync();
  146. //添加的用户不在这个角色中
  147. foreach (var user in users)
  148. {
  149. if (!await _userManager.IsInRoleAsync(user, role.Name))
  150. {
  151. vm.Users.Add(user);
  152. }
  153. }
  154. return View(vm);
  155. }
  156. /// <summary>
  157. /// 在角色中添加一名用户[HttpPost]
  158. /// </summary>
  159. /// <param name="userRoleViewModel"></param>
  160. /// <returns></returns>
  161. [HttpPost]
  162. public async Task<IActionResult> AddUserToRole(UserRoleViewModel userRoleViewModel)
  163. {
  164. var user = await _userManager.FindByIdAsync(userRoleViewModel.UserId);
  165. var role = await _roleManager.FindByIdAsync(userRoleViewModel.RoleId);
  166. if (user != null && role != null)
  167. {
  168. var result = await _userManager.AddToRoleAsync(user, role.Name);
  169. if (result.Succeeded)
  170. {
  171. return RedirectToAction("Index");
  172. }
  173. foreach (var error in result.Errors)
  174. {
  175. ModelState.AddModelError(string.Empty, error.Description);
  176. }
  177. return View(userRoleViewModel);
  178. }
  179. ModelState.AddModelError(string.Empty, "用户或角色没有找到");
  180. return View(userRoleViewModel);
  181. }
  182. /// <summary>
  183. /// 从角色中删除某一用户[HttpGet]
  184. /// </summary>
  185. /// <param name="roleId"></param>
  186. /// <returns></returns>
  187. public async Task<IActionResult> DeleteUserFromRole(string roleId)
  188. {
  189. var role = await _roleManager.FindByIdAsync(roleId);
  190. if (role == null)
  191. {
  192. return RedirectToAction("Index");
  193. }
  194. var vm = new UserRoleViewModel
  195. {
  196. RoleId = role.Id
  197. };
  198. var users = await _userManager.Users.ToListAsync();
  199. foreach (var user in users)
  200. {
  201. if (await _userManager.IsInRoleAsync(user, role.Name))
  202. {
  203. vm.Users.Add(user);
  204. }
  205. }
  206. return View(vm);
  207. }
  208. /// <summary>
  209. /// 从角色中删除某一用户[HttpPost]
  210. /// </summary>
  211. /// <param name="userRoleViewModel"></param>
  212. /// <returns></returns>
  213. [HttpPost]
  214. public async Task<IActionResult> DeleteUserFromRole(UserRoleViewModel userRoleViewModel)
  215. {
  216. var user = await _userManager.FindByIdAsync(userRoleViewModel.UserId);
  217. var role = await _roleManager.FindByIdAsync(userRoleViewModel.RoleId);
  218. if (user != null && role != null)
  219. {
  220. if (await _userManager.IsInRoleAsync(user, role.Name))
  221. {
  222. var result = await _userManager.RemoveFromRoleAsync(user, role.Name);
  223. if (result.Succeeded)
  224. {
  225. return RedirectToAction("EditRole", new { id = role.Id });
  226. }
  227. foreach (var error in result.Errors)
  228. {
  229. ModelState.AddModelError(string.Empty, error.Description);
  230. }
  231. return View(userRoleViewModel);
  232. }
  233. ModelState.AddModelError(string.Empty, "用户不在角色里");
  234. return View(userRoleViewModel);
  235. }
  236. ModelState.AddModelError(string.Empty, "用户或角色未找到");
  237. return View(userRoleViewModel);
  238. }
  239. }
  240. }

对RoleManager的客制化

首先查看源代码,其目的在于查看哪些是现成的,然后决定要客制化哪些新的属性

  1. using System;
  2. namespace Microsoft.AspNetCore.Identity
  3. {
  4. //
  5. // Summary:
  6. // Represents a role in the identity system
  7. //
  8. // Type parameters:
  9. // TKey:
  10. // The type used for the primary key for the role.
  11. public class IdentityRole<TKey> where TKey : IEquatable<TKey>
  12. {
  13. //
  14. // Summary:
  15. // Initializes a new instance of Microsoft.AspNetCore.Identity.IdentityRole`1.
  16. public IdentityRole();
  17. //
  18. // Summary:
  19. // Initializes a new instance of Microsoft.AspNetCore.Identity.IdentityRole`1.
  20. //
  21. // Parameters:
  22. // roleName:
  23. // The role name.
  24. public IdentityRole(string roleName);
  25. //
  26. // Summary:
  27. // Gets or sets the primary key for this role.
  28. public virtual TKey Id { get; set; }
  29. //
  30. // Summary:
  31. // Gets or sets the name for this role.
  32. public virtual string Name { get; set; }
  33. //
  34. // Summary:
  35. // Gets or sets the normalized name for this role.
  36. public virtual string NormalizedName { get; set; }
  37. //
  38. // Summary:
  39. // A random value that should change whenever a role is persisted to the store
  40. public virtual string ConcurrencyStamp { get; set; }
  41. //
  42. // Summary:
  43. // Returns the name of the role.
  44. //
  45. // Returns:
  46. // The name of the role.
  47. public override string ToString();
  48. }
  49. }

牛刀小试,客制化一个超级管理员角色

  1. using Microsoft.AspNetCore.Identity;
  2. namespace Heavy.Web.Models
  3. {
  4. public class ApplicationRole : IdentityRole
  5. {
  6. public string SuperAdminstartor { get; set; }
  7. }
  8. }

测试案例

测试00.测试[Authorize(Roles =”Administrators”)]

  1. 首先验证用户Felix@126.com在不是管理员的情况,能否访问用户管理

image.png
image.png

  1. 添加用户管理

image.png
添加Administrator
image.png

  1. 验证成功

image.png

:::info Tips:若不成功,请LogOut! :::