2017-02-07 80 views
2

我被困在一个我想在asp.net mvc核心应用程序中提供的解决方案中。我想提供一个解决方案,以利用新的基于索赔的方法在Web应用程序中的标准用户,角色,权限。用户角色使用ASP.NET Core Identity的权限3

我一直在关注本福斯特的逻辑在这里(http://benfoster.io/blog/asp-net-identity-role-claims)。在下面的代码中(演示质量),我将说明我将要评论的方法,以帮助显示我的快速和肮脏的测试解决方案。

我面临的挑战是,它没有工作。

//注意:我发现了这个错误,并会为将来寻找类似解决方案的用户发布错误信息。

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

public class DbInitializer 
{ 
    private ApplicationDbContext _context; 
    private RoleManager<ApplicationRole> _roleManager; 
    private UserManager<ApplicationUser> _userManager; 

    public DbInitializer(ApplicationDbContext context,RoleManager<ApplicationRole> roleManager, UserManager<ApplicationUser> userManager) 
    { 
     _roleManager = roleManager; 
     _userManager = userManager; 
     _context = context; 

    } 

    public async Task Initialize() 
    { 
     //RoleManager<IdentityRole> roleManager = new RoleManager<IdentityRole>(); 
     //UserManager<ApplicationUser> userManager = new UserManager<ApplicationUser>(); 

     _context.Database.EnsureCreated(); 

     // Look for any students. 
     if (!_context.Users.Any()) 
     { 
      //create user and admin role 

      ApplicationUser adminUser = new ApplicationUser(); 

      adminUser.Email = "[email protected]"; 
      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 = "[email protected]"; 
      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服务法“政策”。这使我可以将索赔映射到政策或政策。

public void ConfigureServices(IServiceCollection services) 
    { 
     // Add framework services. 
     services.AddDbContext<ApplicationDbContext>(options => 
      options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); 

     services.AddIdentity<ApplicationUser, ApplicationRole>() 
      .AddEntityFrameworkStores<ApplicationDbContext>() 
      .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<DbInitializer>(); 

     // Add application services. 
     services.AddTransient<IEmailSender, AuthMessageSender>(); 
     services.AddTransient<ISmsSender, AuthMessageSender>(); 
    } 

视图:在我的使用情况下,我想从没有与他们被分配到该角色关联的“可以添加角色”要求所有用户限制“添加角色”按钮。其余的视图代码是不相关的。我遇到的问题是,我将声明名称传递给AuthorizationService.AuthorizeAsync作为第二个参数,与'Policy'名称相关联。我已经在下面纠正它。

@model IEnumerable<ApplicationRoleListViewModel> 
@using HailMarry.Models 
@using Microsoft.AspNetCore.Authorization 
@inject IAuthorizationService AuthorizationService 

<br /> 
<div class="top-buffer"></div> 
<div class="panel panel-primary"> 
<div class="panel-heading panel-head">Application Roles</div> 
<div class="panel-body"> 
    <div class="btn-group"> 

     //Mistake 
     //@if (await AuthorizationService.AuthorizeAsync(User, "Can add roles")) 
     //Fix 
     @if (await AuthorizationService.AuthorizeAsync(User, "Add Role")) 
     { 
      <a id="createRoleButton" asp-action="AddRole" asp-controller="ApplicationRole" class="btn btn-primary"> 
       <i class="glyphicon glyphicon-plus"></i> Add Role 
      </a> 
     } 
.... 

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

+0

由于您正在使用角色,因此您可能会发现这篇文章有助于在角色检查中使用特权对象:http://ardalis.com/favor-privileges-over-role-checks – ssmith

回答

0

我发现这个问题,我引用的要求“名称” VS在视图中的政策名称...

我会添加注释上述说明的错误,并显示出我在做什么。非常强大的功能,感谢Ben和ASP.Net提供了超过4.5的改进授权解决方案。

+1

请勿发布anwsers和解决方案在一个更新的问题。把它们放在这里的答案! – Tseng