.NET Core Identity中角色的创建和维护管理发布于 2个月前572 热度0 评论与何人说1 粉丝 31 篇博客关注打赏

.NET Core Identity中角色的创建和维护管理发布于 2个月前572 热度0 评论与何人说1 粉丝 31 篇博客关注打赏

这节我们将介绍在Identity中如何使用Role,在我们应用程序中可以通过ASP.NET Core Identity创建Roles并且该角色可以包含一系列权限来执行应用程序的一系列活动

例如:一个组织可以有4个角色:

1.Admin – 管理员角色给员工分配工作

2.Manager –查看客户需求并按时完成项目

3.Network –用于保持组织的互联网以安全的方式运行。

4.Security - 系统安全相关权限

在ASP.NET Core Identity 我们能创建任何数量的Roles并且可以将这些Roles赋值给Identity Users

一、ASP.NET Core Identity RoleManager类

我们使用ASP.NET Core Identity RoleManager来管理Role,RoleManager 泛型版本T表示Identity在数据库中的Roles。

RoleManager定义了一些重要的功能和属性:

名称

描述

CreateAsync(role)

创建一个新的角色

DeleteAsync(role)

删除一个指定的角色

FindByIdAsync(id)

根据角色Id查找一个角色

FindByNameAsync(name)

根据角色名称查找一个角色

RoleExistsAsync(name)

根据角色名称检查角色是否存在

UpdateAsync(name)

更新角色

Roles

返回Identity中的所有角色

二、Identity中角色管理

我们使用ASP.NET Core Identity实现一个创建和删除角色的功能,创建一个名字为RoleController.cs并且添加如下代码:

public class RoleController : Controller

{

private RoleManager _roleManager;

public RoleController(RoleManager roleManager)

{

_roleManager = roleManager;

}

public IActionResult Index() => View(_roleManager.Roles);

private void Errors(IdentityResult result)

{

foreach (IdentityError error in result.Errors)

ModelState.AddModelError("", error.Description);

}

}

在RoleController中,通过构造函数注入了RoleManager类,我们可以通过依赖注入获取到该类,并使用它来管理Identity角色

private RoleManager _roleManager;

public RoleController(RoleManager roleManager)

{

_roleManager = roleManager;

}

获取所有Identity的角色

RoleManager类Roles属性提供了Identity所有的角色,我们将所有的Roles作为模型类传递给Index视图,代码如下:

public IActionResult Index()

{

return View(_roleManager.Roles);

}

接下来我们在View->Role文件夹下创建一个Index.cshtml文件

@using Microsoft.AspNetCore.Identity;

@model IEnumerable

@{

ViewData["Title"] = "Roles";

}

@foreach (var role in Model)

{

}

编号 角色名称 用户 编辑 删除
@role.Id @role.Name

编辑

这个视图中获取了一个IEnumerable类型集合,它将包含Identity所有Role,我们通过foreach循环将所有Role展示在table内,注意i-role我们使用了第三方Attribute,这个Attribute将调用客户自定义的TagHelper,这个特性会修改td并显示当前角色的用户列表

接下来在项目根目录一下创建一个文件夹CustomTagHelpers,在该文件夹下添加一个RoleUsersTH.cs类,并且该类继承TagHelper,这个类提供自定义的CustomerTagHelper

///

/// 堆代码 duidaima.com

/// 自定义TagHelper

///

[HtmlTargetElement("td", Attributes = "i-role")]

public class RoleUsersTH : TagHelper

{

private UserManager _userManager;

private RoleManager _roleManager;

public RoleUsersTH(UserManager userManager, RoleManager roleManager)

{

_userManager = userManager;

_roleManager = roleManager;

}

[HtmlAttributeName("i-role")]

public string Role { get; set; } = null!;

public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)

{

List names = new List();

var role = await _roleManager.FindByIdAsync(Role);

if (role != null)

{

foreach (var user in _userManager.Users)

{

if (user != null && await _userManager.IsInRoleAsync(user, role.Name ?? ""))

names.Add(user.UserName ?? "");

}

}

output.Content.SetContent(names.Count == 0 ? "No Users" : string.Join(", ", names));

}

}

客户自定义的TagHelper操作td中i-role特性,这个特性获取对应的角色ID,并在后台被处理,我们需要更新_ViewImports.cshtml文件

ASP.NET Core Identity创建角色

我们使用RoleManager的CreateAsync方法创建一个Identity Role,在RoleController类中创建一个CreateAsync方法,代码如下:

public IActionResult Create() => View();

[HttpPost]

public async Task CreateAsync([Required] string name)

{

if (ModelState.IsValid)

{

var result = await _roleManager.CreateAsync(new IdentityRole(name));

if (result.Succeeded)

return RedirectToAction("Index");

else

Errors(result);

}

return View(name);

}

CreateAsync方法入参是name(角色名称)的字符串参数并且使用RoleManager的CreateAsync()方法来创建一个Identity Role

var result = await _roleManager.CreateAsync(new IdentityRole(name));

我们接下来在Views->Role目录下添加一个Create 视图,代码如下:

@model IdentityRole

@{

ViewData["Title"] = "新增角色";

}

ASP.NET Core Identity删除角色

我们使用RoleManager的DeleteAsync()来删除一个Identity Role, 在RoleController.cs的控制器中创建一个DeleteAsync 方法并接受一个角色id(需要删除的角色),代码如下:

public async Task DeleteAsync(string id)

{

//堆代码 duidaima.com

var role = await _roleManager.FindByIdAsync(id);

if (role != null)

{

var identityResult = await _roleManager.DeleteAsync(role);

if (identityResult.Succeeded)

{

return RedirectToAction("Index");

}

else

{

Errors(identityResult);

}

}

else

{

ModelState.AddModelError("", "No role found");

}

return View("Index", _roleManager.Roles);

}

测试Identity创建和删除角色功能

运行应用程序并将URL导航 https://localhost:7296/Role/Create每次创建完一个角色就会跳转到Index View显示Identity数据库中所有的角色创建role页面如下:

我们可以通过这个删除按钮删除Identity 数据库中的Role:

三、添加用户到Roles或从Roles中移除用户

现在我们创建一个新的功能,将完成两件事情:

1.添加用户到指定角色

2.将用户从角色中移除

为了实现这个功能,我们在Models文件加下添加两个类,分别为RoleEdit和RoleModification

public class RoleEdit

{

public IdentityRole? Role { get; set; }

public IEnumerable? Members { get; set; }

public IEnumerable? NoMembers { get; set; }

}

RoleEdit表示一个角色和他关联的用户以及和该角色未关联的用户,RoleModification这个类将帮助我们修改一个角色,具体定义如下:

public class RoleModification

{

[Required]

public string RoleName { get; set; } = null!;

public string RoleId { get; set; } = null!;

public string[]? AddIds { get; set; }

public string[]? DeleteIds { get; set; }

}

这两个类帮助我们将一个用户添加到角色中和从角色中移除用户,我们修改一些RoleController类,添加UpdateAsync方法,下面Get版本的UpdateAsync方法查询两部分数据,属于该角色的用户和不属于该角色的用户

public async Task UpdateAsync(string id)

{

var role = await _roleManager.FindByIdAsync(id);

List members = new List();

List nonMembers = new List();

foreach (var appUser in _userManager.Users)

{

var list = await _userManager.IsInRoleAsync(appUser, role?.Name ?? "") ? members : nonMembers;

list.Add(appUser);

}

return View(new RoleEdit() { Role = role, Members = members, NoMembers = nonMembers });

}

下面Post版本的UpdateAsync方法表示给用户添加和移除角色

[HttpPost]

public async Task UpdateAsync(RoleModification roleModification)

{

if (ModelState.IsValid)

{

foreach (var userId in roleModification.AddIds ?? new string[] { })

{

var appUser = await _userManager.FindByIdAsync(userId);

if (appUser != null)

{

var identityResult = await _userManager.AddToRoleAsync(appUser, roleModification.RoleName);

if (!identityResult.Succeeded)

Errors(identityResult);

}

}

foreach (var userId in roleModification.DeleteIds ?? new string[] { })

{

var appUser = await _userManager.FindByIdAsync(userId);

if (appUser != null)

{

var identityResult = await _userManager.RemoveFromRoleAsync(appUser, roleModification.RoleName);

if (!identityResult.Succeeded)

Errors(identityResult);

}

}

}

if (ModelState.IsValid)

return RedirectToAction(nameof(Index));

else

return await UpdateAsync(roleModification.RoleId);

}

注意我们在构造函数中添加了UserManager依赖:

private RoleManager _roleManager;

private UserManager _userManager;

public RoleController(RoleManager roleManager, UserManager userManager)

{

//堆代码 duidaima.com

_roleManager = roleManager;

_userManager = userManager;

}

我们使用UserManager类的下面方法类管理ASP.NET Core Identity Roles

名称

描述

AddToRoleAsync(AppUser user, string name)

将用户添加到指定角色中

RemoveFromRoleAsync(AppUser user, string name)

从指定角色中删除用户

GetRolesAsync(AppUser user)

获取当前用户所有角色

IsInRoleAsync(AppUser user, string name)

判断一个用户是否是指定的角色成员如果是返回ture,否则false

接下来,在Views -> Role 文件夹下添加Update.csthml,代码如下:

@model RoleEdit

@{

ViewData["Title"] = "编辑角色";

}

@Model.Role.Name 角色包含的用户

@if (!Model.Members!.Any())

{

}

else

{

foreach (var appUser in Model.Members ?? new List())

{

}

}

该角色没有关联任何用户
@appUser.UserName

@Model.Role.Name 角色未包含的用户

@if (!Model.NoMembers!.Any())

{

}

else

{

foreach (var appUser in Model.NoMembers ?? new List())

{

}

}

该角色保护所有用户
@appUser.UserName

这个页面包含两个Table:

1.当前角色包含的用户

2.当前角色未包含的用户

我们可以选择对应的 checkbox给角色添加和删除用户

测试更新功能

我们先注册三个用户(密码为:Coder77@1):

同时我们也创建了三个角色:

我们查看当前每个角色都没有用户:

一个用户可以指定多个角色,使用这个功能仅仅完成了ASP.NET Core Identity 更新角色的功能,下面我们将实现基于角色的认证

四、基于ASP.NET Core Identity Role 认证

ASP.NET Core Identity 角色可以作为认证,特定角色所包含的用户能访问特定的资源。例如:我们给指定方法设定一个[Authorize(Roles = “SomeRole”)]特性,这个角色下的所有用户都能访问这个方法,在HomeController的Index方法添加Authorize特性[Authorize(Roles = "Manager")] , 指明只有Manager角色的用户才能访问HomeController的Index 方法,代码如下:

public class HomeController : Controller

{

private readonly ILogger _logger;

private UserManager _userManager;

public HomeController(UserManager userManager, ILogger logger)

{

_userManager = userManager;

_logger = logger;

}

[Authorize(Roles = "Manager")]

public async Task Index()

{

var appUser = await _userManager.GetUserAsync(HttpContext.User);

var message = "Hello " + appUser?.UserName;

return View((object)message);

}

}

运行应用程序,使用tom登录,访问HomeController方法我们可以正常访问HomeController的Index方法,因为tom所拥有的角色是Manager。现在我们使用alice 用户进行登录,alice不属于Manager角色,所以当我们尝试访问Home/Index时,应用程序将会跳转到https://localhost:7296

/Account/AccessDenied?ReturnUrl=%2F,因为AccountController控制器中没有创建AccessDenied方法,因此会获取一个HTTP 404 错误,因此我们在ActionController下创建一个AccessDenied方法:

public IActionResult AccessDenied()

{

return View();

}

在Views->Account目录下添加AccessDenied.cshtml视图,代码如下:

Access Denied

退出登录

现在,运行应用程序,并进入登录页面https://localhost:7296

/Account/Login.

使用 alice账户登录:

邮箱–alice@yahoo.com

密码– Coder77@1

登录之后将被调转到Denied URL, 如下图所示:

Identity为我们提供设置了一个默认的/Account/AccessDenied URL地址,我们可以通过配置改变这个地址:

builder.Services.ConfigureApplicationCookie(

opts =>

{

//默认登录页面

opts.LoginPath = "/Account/Login";

opts.AccessDeniedPath= "/Account/AccessDenied";

//设置Cookie名称

opts.Cookie.Name = ".AspNetCore.Identity.Application";

//设置Cookie超时时间

opts.ExpireTimeSpan = TimeSpan.FromMinutes(20);

//设置滑动时间

opts.SlidingExpiration = true;

}

);

总结

这节我们主要讲解了Identity角色管理和身份认证

养生小贴士

时空猎人怎么改密码 时空猎人密码如何改
💡 小知识

时空猎人怎么改密码 时空猎人密码如何改

📅 10-17 👍 182
土阜的意思
💡 小知识

土阜的意思

📅 08-23 👍 708
《战双帕弥什》换绑手机方法介绍
💡 小知识

《战双帕弥什》换绑手机方法介绍

📅 10-15 👍 730