首页 文章

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

提问于
浏览
7

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

我这里的逻辑是've been following Ben Foster'(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 = "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<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作为第二个参数vs'Policy'名称,该名称具有与之关联的声明 . 我已经在下面纠正了它 .

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


<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> } ....

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

1 回答

  • 2

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

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

相关问题