如何使用Entity Framework设计可配置的字段级权限

cSt*_*off 11 c# sql-server permissions entity-framework

假设我们有一个关于某些型号汽车的信息表,例如: 在此输入图像描述

如果我还需要用户可配置的规则,我如何才能最好地实现读写操作的字段级访问权限?我正在使用MSSQL Server 2016和EF 6.

根据该表,我们可能会有以下用例,用于描述某个角色或组可见的字段:

1)公共数据的默认权限组

在此输入图像描述

2)基于实体的权限组

在此输入图像描述

3)基于自定义字段的权限组

在此输入图像描述

要求是,隐藏数据必须与NULL值不同,规则/权限必须是用户可配置的.我还需要对列表进行分页,这需要对可见数据进行正确排序.为此,我需要一种处理数据类型的方法.例如,建设年度为一个非空的日期时间,然而,当该场是不可见的,它需要被设置为像DateTime.MinValue默认值.处理位(布尔值)时,这变得更具挑战性:-)

我目前正在考虑与任何一个表值函数的方法,这似乎是动态地实现对我的情况下,或保存数据,这是我需要保持同步与数据库的全部单独的缓存层更难.

Luc*_*umb 3

实现目标的一种简单方法是创建一个设置表,在其中按组指定每个字段的可见性。

首先,您需要创建一个组(品牌)表,如下所示:

 public class Group
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

那么您将需要一个用于可见性设置的表:

  public class TableVisibilitySettings
    {
        public int Id { get; set; }
        public int GroupId { get; set; }
        public virtual Group Group { get; set; }
        public bool ContructionYear { get; set; }
        public bool Power { get; set; }
        public bool IsConvertible { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

然后你将需要你的表和视图模型:

public class Table
    {
        public int Id { get; set; }
        public int GroupId { get; set; }
        public virtual Group Grup { get; set; }

        public string Color { get; set; }
        public int? ConstructionYear { get; set; }
        public string Power { get; set; }
        public bool? IsConvertible { get; set; }


        public IEnumerable<TableVm> GetTableByGroupType(int groupId, ApplicationDbContext context)
        {
            var table = context.Tables.ToList();
            var visibility = context.TableVisibilitySettings.FirstOrDefault(x => x.GroupId == groupId);

            return table.Select(x => new TableVm
            {
                Id = x.Id,
                Brand= x.Grup.Name,
                Color = x.Color,
                ConstructionYear = visibility.ContructionYear == true ? x.ConstructionYear : null,
                Power = visibility.Power == true ? x.Power : null,
                IsConvertible = visibility.IsConvertible == true ? x.IsConvertible : null
            }).ToList();
        }
    }
Run Code Online (Sandbox Code Playgroud)

使用该方法,GetTableByGroupType您可以根据每个组的可见性设置检索数据库。

如果您愿意,可以使用角色而不是组。

编辑:

应用分页的一种方法可以是这样的:

 public IEnumerable<TableVm> GetTableByGroupWithPag(int groupId, ApplicationDbContext context,int pageNumber, int rowsPerPage)
        {

            var table = context.Tables.Skip((pageNumber-1)*rowsPerPage).Take(rowsPerPage).ToList();

            var visibility = context.TableVisibilitySettings.FirstOrDefault(x => x.GroupId == groupId);

            return table.Select(x => new TableVm
            {
                Id = x.Id,
                Group = x.Grup.Name,
                Color = x.Color,
                ConstructionYear = visibility.ContructionYear == true ? x.ConstructionYear : null,
                Power = visibility.Power == true ? x.Power : null,
                IsConvertible = visibility.IsConvertible == true ? x.IsConvertible : null
            }).ToList();
        }
Run Code Online (Sandbox Code Playgroud)

首先,您需要从表中获取要显示的行,然后只需要应用可见性设置。

编辑:

有多种方法可以将组链接到用户,具体取决于您的应用程序设计和您的技能。最简单的方法是设置one to one, 或和many to many之间的关系,如下所示:ApplicationUserGroup

public class ApplicationUser
{
 ...
 public int GroupId {get;set;}
 public virtual Group Group
}
Run Code Online (Sandbox Code Playgroud)

并且在 Group 类中您需要添加:

 public virtual ICollection<ApplicationUser> Users {get;set;}
Run Code Online (Sandbox Code Playgroud)

另一种方法是为每个品牌创建角色,并根据您希望他读/写的品牌为每个用户提供一个或多个角色。

另一种方法是使用声明,您所需要做的就是向每个用户添加代表 groupId 或 groupName 或品牌的声明。

希望这将帮助您选择将用户链接到组的方法。