用户角色使用ASP.NET Core Identity 3的权限

我坚持使用我想在asp.net mvc核心应用程序中提供的解决方案。 我想在Web应用程序中提供标准用户,角色,权限的解决方案,以利用新的基于声明的方法。

我一直在关注Ben Foster的逻辑( http://benfoster.io/blog/asp-net-identity-role-claims )。 在下面的代码(演示质量)中,我将阐述我的方法,我将评论以帮助显示我快速而肮脏的测试解决方案。

我遇到的挑战是它不起作用。

//注意:我发现了这个错误,并会在未来用户寻找类似解决方案的地方发表评论。

种子类:这是一个快速而肮脏的解决方案,用两个新用户,两个角色和一个角色的一些声明为数据库播种。 我这样做是一个测试应用程序,用于学习管理我的应用程序授权的声明方法。 我的完整解决方案将为每个租户提供一种方式,通过UI创建自己的角色,将1个或多个声明与角色相关联,然后为用户分配角色。 我想为租户提供一种管理自己用户以及他们能做什么或不做什么的方法。 这是基于声明的方法的简单实现,因为权利要求比与策略的1:1关系具有更多的权力。

public class DbInitializer { private ApplicationDbContext _context; private RoleManager _roleManager; private UserManager _userManager; public DbInitializer(ApplicationDbContext context,RoleManager roleManager, UserManager userManager) { _roleManager = roleManager; _userManager = userManager; _context = context; } public async Task Initialize() { //RoleManager roleManager = new RoleManager(); //UserManager userManager = new UserManager(); _context.Database.EnsureCreated(); // Look for any students. if (!_context.Users.Any()) { //create user and admin role ApplicationUser adminUser = new ApplicationUser(); adminUser.Email = "admin@company.com"; adminUser.UserName = "Admin"; var result = await _userManager.CreateAsync(adminUser, "Password-1"); var newAdminUser = await _userManager.FindByEmailAsync(adminUser.Email); ApplicationRole adminRole = new ApplicationRole(); adminRole.Name = "Admin"; adminRole.Description = "This is the admin role."; await _roleManager.CreateAsync(adminRole); await _roleManager.AddClaimAsync(adminRole, new Claim("Can add roles", "add.role")); await _roleManager.AddClaimAsync(adminRole, new Claim("Can delete roles", "delete.role")); await _roleManager.AddClaimAsync(adminRole, new Claim("Can edit roles", "edit.role")); await _userManager.AddToRoleAsync(newAdminUser, adminRole.Name); //create user and basic role ApplicationUser basicUser = new ApplicationUser(); basicUser.Email = "basic@company.com"; basicUser.UserName = "Basic"; var resultBasic = await _userManager.CreateAsync(basicUser, "Password-1"); var newBasicUser = await _userManager.FindByEmailAsync(basicUser.Email); ApplicationRole basicRole = new ApplicationRole(); basicRole.Name = "Basic"; basicRole.Description = "This is the basic role."; await _roleManager.CreateAsync(basicRole); //await _roleManager.AddClaimAsync(basicRole, new Claim("Can add roles", "add.role")); //await _roleManager.AddClaimAsync(basicRole, new Claim("Can delete roles", "delete.role")); //await _roleManager.AddClaimAsync(basicRole, new Claim("Can edit roles", "edit.role")); await _userManager.AddToRoleAsync(newBasicUser, basicRole.Name); await _context.SaveChangesAsync(); } } } } 

Startup.CS:在创建用户,角色和声明(并关联它们)之后,我需要在Startup.cs类的Confirgure Services方法中注册“Policies”。 这允许我将声明映射到一个或多个策略。

  public void ConfigureServices(IServiceCollection services) { // Add framework services. services.AddDbContext(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); services.AddIdentity() .AddEntityFrameworkStores() .AddDefaultTokenProviders(); services.AddAuthorization(options => { options.AddPolicy("Add Role", policy => policy.RequireClaim("Can add roles", "add.role")); options.AddPolicy("Edit Role", policy => policy.RequireClaim("Can edit roles", "edit.role")); options.AddPolicy("Delete Role", policy => policy.RequireClaim("Can delete roles", "delete.role")); }); services.AddMvc(); services.AddTransient(); // Add application services. services.AddTransient(); services.AddTransient(); } 

查看:在我的用例中,我想限制任何没有“可添加角色”声明的用户的“添加角色”按钮,该声明与分配给他们的角色相关联。 视图代码的其余部分不相关。 我遇到的问题是我将声明名称传递给AuthorizationService.AuthorizeAsync作为第二个参数vs’Policy’名称,该名称具有与之关联的声明。 我已经在下面纠正了它。

 @model IEnumerable @using HailMarry.Models @using Microsoft.AspNetCore.Authorization @inject IAuthorizationService AuthorizationService 
Application Roles
//Mistake //@if (await AuthorizationService.AuthorizeAsync(User, "Can add roles")) //Fix @if (await AuthorizationService.AuthorizeAsync(User, "Add Role")) { Add Role } ....

最终结果:我有一个用户“admin@company.com”,该用户被分配到角色“Admin”,其中有一个声明“可以添加角色”。 角色可以有任意数量的声明。 我创建了一个策略,它具有相同的声明“可以添加角色”,我通过注入IAuthorizationService AuthorizationService在View中检查。 如果用户未将此声明分配给其角色,则返回true或false的策略检查将不会显示添加角色的按钮。 由于新的.net核心DI中间件,可以通过DI将相同的策略检查逻辑添加到控制器或任何其他资源。 通过这整个练习,我学会了Identity 3的强大function,它可以利用业务逻辑检查等function。 非常甜蜜的东西,虽然那里的作家真的需要更多的例子来帮助我们更快地获得肉。 无论如何,希望这有助于未来的开发人员寻找类似的解决方案。

我发现了这个问题,我在视图中引用了声明’name’与策略名称…

我将在上面添加注释来说明错误并展示我正在做的事情。 非常强大的function,感谢Ben和ASP.Net提供了超过4.5的改进授权解决方案。