Asp.net mvc 以编程方式向用户授予特定表权限的最佳方法?

Asp.net mvc 以编程方式向用户授予特定表权限的最佳方法?,asp.net-mvc,entity-framework,ef-code-first,user-permissions,Asp.net Mvc,Entity Framework,Ef Code First,User Permissions,我们有一个现有的工作系统,我被要求改变当前授予用户权限的逻辑。当前的逻辑不是很合适,就性能而言,它太慢了 当前结构 目前,我们有25个表以及更多的表,我们有110个系统用户。有些是管理员,有些是具有特定权限的简单用户。我们在系统中使用M-V-C实体框架代码优先的方法 对于每个表,我们都有5个复选框,第一个复选框用于授予访问页面的权限,第二个复选框用于创建数据,第三个复选框用于读取数据,第四个复选框用于更新数据,第五个复选框用于删除数据 问题 现在所有这些权限都在一个用户表中,所以用户表中总共有1

我们有一个现有的工作系统,我被要求改变当前授予用户权限的逻辑。当前的逻辑不是很合适,就性能而言,它太慢了

当前结构 目前,我们有25个表以及更多的表,我们有110个系统用户。有些是管理员,有些是具有特定权限的简单用户。我们在系统中使用M-V-C实体框架代码优先的方法

对于每个表,我们都有5个复选框,第一个复选框用于授予访问页面的权限,第二个复选框用于创建数据,第三个复选框用于读取数据,第四个复选框用于更新数据,第五个复选框用于删除数据

问题 现在所有这些权限都在一个用户表中,所以用户表中总共有125列。25个表x 5个复选框=125列

所以,当我们注册用户时,我们可以选择权限,例如,user1只能从country表中读取国家记录,只能从cities表中添加或编辑城市,只能从Relights表中删除宗教

此外,系统中有125个不同的角色。e、 g.CountryCreate、CountryDelete、CityCreate、CityDelete等

在用户注册期间,系统根据选中的值将不同的角色与用户关联。所以让我们假设,如果管理员想给用户70个权限,那么70个角色将与该特定用户关联,因为有很多用户,所以有数千个用户角色。创建角色是为了签入视图,如果用户是特定角色,则显示特定功能,例如国家/地区创建,否则不显示

应用程序大部分时间停止工作。因为与每个用户关联的角色和复选框太多了

我是这个项目的新手,第一项工作是更改权限逻辑。实现这一目标的最佳方式是什么

现行代码 像这样,我们有125条if语句,它只用于寄存器。在edit中,如果复选框为false,我们还可以从角色中删除else语句。另外,我们在用户模型中有125个属性


解决此问题的最佳方法是什么?

在不了解项目结构或瓶颈实际位置的情况下,很难给出建议,但为了帮助解决性能问题,您至少可以做5件事:

与其使用5个布尔字段作为权限,不如使用单个按位int字段,并将值转换为UI上的5个复选框。例如,1=访问;2=创建;4=读取;8=更新;16=删除,因此如果字段的值为13,则用户将有权访问、读取和更新1+4+8=13。 不清楚为什么每个表都有一列。每个表都有一行更有意义,然后您可以有一列权限。 同时拥有复选框和角色听起来有点过分了。如果您的每个角色都是权限,则可以完全删除权限表。 通过使用System.Runtime.caching.MemoryCache在内存中缓存权限和/或角色,可以显著提高性能。 确保您的角色/权限没有保存在cookie中,因为这意味着每个HTTP请求(无论是页面、图像、CSS文件等)都会发送cookie往返,这会转化为大量额外的网络流量字节。 权限表 不确定客户为什么想要这张桌子。也许他们想要已经作为角色存在的数据,而这正是您解释它的方式。您的第一选择应该是消除数据重复,只使用角色,因为角色很容易被MVC使用

如果不可能,那么这就是你可以做的事情

UserID | Table (string)           | Permission (int)
---------------------------------------------------
1      | Table1                   | 13
1      | Table2                   | 17
2      | Table5                   | 3

请记住,控制权限的是您的应用程序,而不是数据的实际存储方式。但可维护的数据库只能在一个地方存储数据,让应用程序处理如何使用、显示和更新数据。

您可以采用以下方法:

您已经有了用户和角色模型。您只需要另一个具有此结构的模型:

public enum Actions
{
    Insert,
    Delete,
    Update,
    GetOne,
    GetAll
}

public enum Services
{
    Country,
    Category,
    Product,
    Warehouse
}

public class UserAccess
{
    public int Id { get; set; }
    public ApplicationRole Role { get; set; }
    public string Title { get; set; }
    public Actions Action { get; set; }
    public Services Service { get; set; }
}
使用此模型,您可以定义无限访问。用户具有角色 每个角色都可以有很多用户访问权限

之后,您必须像125 if语句一样手动检查它,或者使用更好的方法,我建议您使用Web API:

首先,您必须继承AuthorizeAttribute类,并使用访问模型(如用户、角色和用户访问)对其进行自定义,还必须重写授权方法,如:

public class ServiceAuthorize : AuthorizeAttribute
    {
        public ServiceAuthorize(Actions action, params Services[] services)
        {
            this.action = action;
            this.services = services.ToList();
        }
        private Actions action { get; set; }
        private List<Services> services { get; set; }
        public override void OnAuthorization(HttpActionContext actionContext)
        {
              // check the user's roles here
              // if the user don't have needed role or access you can reject it with this code
             if (Unauthorized)
             {
                 actionContext.Response = actionContext.Request.CreateResponse(
                                    HttpStatusCode.Unauthorized,
                                    new Dictionary<string, string> {
                                                { HttpStatusCode.Unauthorized.ToString(), ((int)HttpStatusCode.Unauthorized).ToString() }
                                   }
                   );
             } 
        }
    } 

我希望这会有所帮助。

您处理权限的方式没有问题。事实上,这是一种处理权限的方式。如果你的应用程序崩溃了,那是另外一个无关的问题。要么代码不好,要么效率低下,服务器没有足够的资源,数据库需要调整,等等。您根据自己的体系结构塑造环境
,而不是相反。那么您的意思是拥有125列和角色的表不是问题?定义问题。这并不是说在你不得不放弃你的方法重新开始之前,你可以拥有很多神奇的东西。您正在构建一个应用程序来满足您的业务需求。无论需要做什么,这都是必需的。从理论上讲,在SQL表中有125列这样的内容并没有什么固有的问题。它不像SQL Server那样不,我只支持124。现在你被烤熟了。如果存在性能问题或其他问题,您可以通过添加更多资源等其他方式解决这些问题。不过,我会说,如果您将每个角色中的用户成员身份存储为某个表中的一列,那么这是错误的方法。是否选中表单中的复选框应取决于用户的现有角色成员身份,而不是某些表中的某些标志。您实际上是通过存储实际的复选框值来反规范化您的数据。根据所有角色的列表构建您的复选框列表,然后根据用户是否实际担任该角色来选中该复选框。是的,我也在考虑使用int而不是bool。第二次我不明白,你说的一列权限是什么意思?是的,我可以删除权限表,但客户需要该表。
public class ServiceAuthorize : AuthorizeAttribute
    {
        public ServiceAuthorize(Actions action, params Services[] services)
        {
            this.action = action;
            this.services = services.ToList();
        }
        private Actions action { get; set; }
        private List<Services> services { get; set; }
        public override void OnAuthorization(HttpActionContext actionContext)
        {
              // check the user's roles here
              // if the user don't have needed role or access you can reject it with this code
             if (Unauthorized)
             {
                 actionContext.Response = actionContext.Request.CreateResponse(
                                    HttpStatusCode.Unauthorized,
                                    new Dictionary<string, string> {
                                                { HttpStatusCode.Unauthorized.ToString(), ((int)HttpStatusCode.Unauthorized).ToString() }
                                   }
                   );
             } 
        }
    } 
 public class CountryController : ApiController
    {
        [ServiceAuthorize(new List<Actions>() { Actions.GetAll }, new List<Services>() { Services.Country })]
        public string GetCountries()
        {

        }

        [ServiceAuthorize(new List<Actions>() { Actions.Insert }, new List<Services>() { Services.Country })]
         public string AddCountry(Country country)
         {

         }
    }