如何在asp.net core中添加多个身份和多个角色

Posted

技术标签:

【中文标题】如何在asp.net core中添加多个身份和多个角色【英文标题】:How to add multiple identity and multiple role in asp.net core 【发布时间】:2021-01-29 20:31:40 【问题描述】:

我是 asp.net 核心的新手。所以这可能不是一个好问题。

我有 3 个课程:AdminDoctorPatient

我希望所有这些用户都能够登录并查看他们的仪表板。它们都将具有不同级别的访问权限。

所以我从IdenetityUser 派生了这些类,如下所示:

public class Admin : IdentityUser



public class Doctor : IdentityUser

    public const int MaxAppointPerDay = 28;

    public Gender Gender  get; set; 


public class Patient : IdentityUser

    public DateTime DateOfBirth  get; set; 
    public Gender Gender  get; set; 

我只是在这之后被卡住了。

当我尝试通过 AddIdentity<TUser, TRole>() 方法添加多个身份时,它给了我错误。

接下来我该怎么做?

互联网上的大多数示例都涉及一个IdentityUser和多个IdentityRole。但是由于用户模型都不同,我不能那样做。

谢谢。

【问题讨论】:

您可以使用多个属性扩展您的基本身份模型并管理对角色的访问。我可以推荐你,而不是创建多个表来管理你的用户。这将为您做很多工作,并且您不能使用标准实现。如果有人想要护士的访问级别会发生什么? 您不能重复使用AddIdentity 来添加身份。 ASP.NET Core 提供了一个内置方法:AddIdentityCore<TUser> 可以这样使用:services.AddIdentityCore<Admin>(); @Yinqiu 如果我使用AddIdentityCore,我可以添加多个身份吗? 是的,你可以试试。 嗨@Muzib,关于此案的任何更新? 【参考方案1】:

您不能重复使用AddIdentity 来添加身份。

ASP.NET Core 提供了一个内置方法:AddIdentityCore<TUser>

你可以这样使用它:services.AddIdentityCore<Admin>();

编辑:

补充银秋的答案,对于以后的读者,如果你使用这个AddIdentityCore方法,AspNetUsers表将合并每个IdentityUser的所有属性。这是一个例子:

TeacherStudent 是两个IdentityUser,并且它们都至少有一个不同的属性,如下所示:

public class Teacher : IdentityUser

    public string Subject  get; set; 


public class Student : IdentityUser

    public int Grade  get; set; 

然后我在startup.cs 中添加他们的两个身份,如下所示:

services.AddIdentityCore<Teacher>().AddEntityFrameworkStores<AppDbContext>();
services.AddIdentityCore<Student>().AddEntityFrameworkStores<AppDbContext>();

AspNetUsers 表将包括Subject 属性和Grade 属性。这是迁移类的证明:

migrationBuilder.CreateTable(
    name: "AspNetUsers",
    columns: table => new
    
        Id = table.Column<string>(nullable: false),
        UserName = table.Column<string>(maxLength: 256, nullable: true),
        NormalizedUserName = table.Column<string>(maxLength: 256, nullable: true),
        Email = table.Column<string>(maxLength: 256, nullable: true),
        NormalizedEmail = table.Column<string>(maxLength: 256, nullable: true),
        EmailConfirmed = table.Column<bool>(nullable: false),
        PasswordHash = table.Column<string>(nullable: true),
        SecurityStamp = table.Column<string>(nullable: true),
        ConcurrencyStamp = table.Column<string>(nullable: true),
        PhoneNumber = table.Column<string>(nullable: true),
        PhoneNumberConfirmed = table.Column<bool>(nullable: false),
        TwoFactorEnabled = table.Column<bool>(nullable: false),
        LockoutEnd = table.Column<DateTimeOffset>(nullable: true),
        LockoutEnabled = table.Column<bool>(nullable: false),
        AccessFailedCount = table.Column<int>(nullable: false),
        Discriminator = table.Column<string>(nullable: false),
        Grade = table.Column<int>(nullable: true),
        Subject = table.Column<string>(nullable: true)
    ,
    constraints: table =>
    
        table.PrimaryKey("PK_AspNetUsers", x => x.Id);
    );

注意最后两个属性是GradeSubject

这类似于为所有 IdentitiyUser 使用基类,该基类将派生自 IdentityUser 并包含所有属性的组合,然后使用 AddIdentity&lt;TUser, TRole&gt; 方法添加一个基类。

【讨论】:

【参考方案2】:

您可以像在 Active Directory 中实现的那样执行此操作,而不是为每个访问级别组创建一个新表(实体),您可以只创建一个用于存储访问级别组 Admin , Doctor , Patient 的新表(实体),依此类推。并将IdenetityUser 加入任何组... 当然,每个组都应该有一些角色。

例如-型号:

    public class BaseGuidIdTable

    [Key]
    public Guid Id  get; set; 

    public class SecurityGroupRole: BaseGuidIdTable


    public string Role  get; set; 

    public string Description  get; set; 


    public class SecurityRight: BaseGuidIdTable


    public string Right  get; set; 

    public string Description  get; set; 


    public class SecurityGroupAccess: BaseGuidIdTable


    public Guid GroupId  get; set; 

    [ForeignKey(nameof(GroupId))]
    public SecurityGroupRole GroupRole  get; set; 

    public Guid RightId  get; set; 

    [ForeignKey(nameof(RightId))]
    public SecurityRight Right  get; set; 

添加一些数据:

            builder.Entity<SecurityGroupRole>().HasData(
            new SecurityGroupRole
            
                Id = new Guid(OwnerGuidTxt),
                Role = "Doctor",
                Description = "Doctor"
            ,
            new SecurityGroupRole
            
                Id = new Guid(AdminGuidTxt),
                Role = "Admin",
                Description = "Admin"
            ,
            new SecurityGroupRole
            
                Id = new Guid(UserGuidTxt),
                Role = "Patient",
                Description = "Patient"
            

        );
            builder.Entity<SecurityRight>().HasData(
            new SecurityRight
            
                Id = new Guid(AddDeleteNewUsers),
                Right = "AddDeleteNewUsers",
                Description = "Add or delete Users"
            ,
            new SecurityRight
            
                Id = new Guid(PasswordChangeYourself),
                Right = "PasswordChangeYourself",
                Description = "Can password change by yourself"
            ,
            new SecurityRight
            
                Id = new Guid(ViewAll),
                Right = "ViewAll",
                Description = "Can view all objects"
            ,
            new SecurityRight
            
                Id = new Guid(CanChangeTags),
                Right = "CanChangeTags",
                Description = "Can change tags"
             
        );
                new SecurityGroupAccess Id = new Guid("DD4C2CC3-65E2-4DD1-A620-723B5ADB8758"), GroupId = ownerGroupGuid, RightId = new Guid(AddDeleteNewUsers) ,
            new SecurityGroupAccess  Id = new Guid("23CD8B4E-A572-4335-B1EF-2EF115E14947"), GroupId = ownerGroupGuid, RightId = new Guid(PasswordChangeYourself) ,
            new SecurityGroupAccess  Id = new Guid("6A6A3A41-1103-46BD-B482-AB59903172D9"), GroupId = ownerGroupGuid, RightId = new Guid(ViewAll) ,
            new SecurityGroupAccess  Id = new Guid("EB133F40-AB3B-4094-9AE7-EF6FD853F36B"), GroupId = ownerGroupGuid, RightId = new Guid(CanChangeTags) ,

            new SecurityGroupAccess  Id = new Guid("29EE3EDA-08ED-46F1-9EF7-79A2D4021E86"), GroupId = adminGroupGuid, RightId = new Guid(PasswordChangeYourself) ,
            new SecurityGroupAccess  Id = new Guid("59309220-F49B-4E30-B265-CB2ED71867B0"), GroupId = adminGroupGuid, RightId = new Guid(ViewAll) ,
            new SecurityGroupAccess  Id = new Guid("F2F3FDF3-1ABC-46FF-BB62-E19B3F48E0AC"), GroupId = adminGroupGuid, RightId = new Guid(CanChangeTags) ,

            new SecurityGroupAccess  Id = new Guid("7AC0F6A1-A585-40D6-B09B-DD6B86772935"), GroupId = userGroupGuid, RightId = new Guid(PasswordChangeYourself) 

所以 - 在示例中,我们添加 3 个 SecurityGroupRole Admin , Doctor , Patient,并赋予每个权限,Patient 可以为自己更改密码(对不起 - 这是来自其他项目 - 所以命名可能看起来错误)

【讨论】:

我认为IdentityRole 可以完成您建议的工作。 @Muzib - 是的 - 如此处所述docs.microsoft.com/en-us/aspnet/core/security/authentication/…

以上是关于如何在asp.net core中添加多个身份和多个角色的主要内容,如果未能解决你的问题,请参考以下文章

在 ASP.NET Core 中使用多个身份验证方案

尝试对 ASP.NET Core 3.1 使用多个身份验证方案时出现异常

在 asp.net core 3.1+ 中使用多个中间件进行身份验证和授权

ASP.NET Core 2.0 中的多个身份

如何在 ASP.NET Core MVC 的同一视图中添加/创建多个一对多关系

如何在 Asp.Net Core 2.0“AddJwtBearer”中间件中设置多个受众?