Asp.net核心身份用户的多个角色

时间:2020-01-14 15:48:04

标签: asp.net-core identity claims-based-identity policy role-base-authorization

我正在研究asp.net core 3.1项目。项目中有几种类型的用户。例如:

某些用户输入

管理员

作家

经理

会计师

操作员

和...

用户类型不同,可能会增加或减少。在此项目中,我们可能有20位作者或100位操作员用户,所有作者或所有操作员都具有相同的角色。 现在,我可以手动为用户设置角色。但我想为用户设置一堆角色。 例如,如果用户类型是操作员,则所有角色都取决于设置为用户的操作员。

1 个答案:

答案 0 :(得分:2)

我创建了一个简单的演示,您可以在注册用户时选择UserType。并将UserType的所有相关角色分配给用户。

1。型号:

public class ApplicationUser : IdentityUser
{
    [ForeignKey("UserType")]
    public int UserTypeId {get;set;}
    public UserType UserType { get; set; }
}

public class UserType
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }

    public List<ApplicationUser> Users { get; set; }
    public List<ApplicationRole> Roles { get; set; }
}

public class ApplicationRole : IdentityRole
{
    [ForeignKey("UserType")]
    public int? UserTypeId {get;set;}
    public UserType UserType { get; set; }
}

2.DbContext

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }

    public DbSet<UserType> UserTypes { get; set; }
    public DbSet<ApplicationRole> AppRoles { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);


        modelBuilder.Entity<ApplicationUser>()
        .HasOne(c => c.UserType)
        .WithMany(u=>u.Users)
        .OnDelete(DeleteBehavior.Restrict);


    }
}

3.Register.cshtml.cs

public class InputModel
    {

        [Required]
        [EmailAddress]
        [Display(Name = "Email")]
        public string Email { get; set; }

        [Required]
        [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
        [DataType(DataType.Password)]
        [Display(Name = "Password")]
        public string Password { get; set; }

        [DataType(DataType.Password)]
        [Display(Name = "Confirm password")]
        [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
        public string ConfirmPassword { get; set; }

        public int UserTypeId { get; set; }
    }

public async Task OnGetAsync(string returnUrl = null)
    {

        ViewData["UserType"] = new SelectList(_context.UserTypes, "Id", "Name");

        ReturnUrl = returnUrl;
        ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
    }

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
    {

        returnUrl = returnUrl ?? Url.Content("~/");
        ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
        if (ModelState.IsValid)
        {
            var user = new ApplicationUser { UserName = Input.Email, Email = Input.Email, UserTypeId = Input.UserTypeId };
            var result = await _userManager.CreateAsync(user, Input.Password);
            if (result.Succeeded)
            {
                //add bunch of roles to user
                var roles = _context.AppRoles.Where(r => r.UserTypeId == user.UserTypeId).Select(r => r.Name).ToList();
                foreach(var role in roles)
                {
                   await _userManager.AddToRoleAsync(user, role);
                }

               //...
            }
            foreach (var error in result.Errors)
            {
                ModelState.AddModelError(string.Empty, error.Description);
            }
        }

        // If we got this far, something failed, redisplay form
        return Page();
    }

4.Register.cshtml

<form asp-route-returnUrl="@Model.ReturnUrl" method="post">
        <h4>Create a new account.</h4>
        <hr />
        <div asp-validation-summary="All" class="text-danger"></div>
        <div class="form-group">
            <label asp-for="Input.Email"></label>
            <input asp-for="Input.Email" class="form-control" />
            <span asp-validation-for="Input.Email" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="Input.Password"></label>
            <input asp-for="Input.Password" class="form-control" />
            <span asp-validation-for="Input.Password" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="Input.ConfirmPassword"></label>
            <input asp-for="Input.ConfirmPassword" class="form-control" />
            <span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="Input.UserTypeId"></label>
            <select asp-for="Input.UserTypeId" asp-items="@ViewBag.UserType" class="form-control"></select>

        </div>
        <button type="submit" class="btn btn-primary">Register</button>
 </form>

4.Startup.cs

services.AddDefaultIdentity<ApplicationUser>()
            .AddRoles<ApplicationRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>();