以编程方式向用户提供特定表权限的最佳方法?

时间:2017-05-31 14:14:24

标签: asp.net-mvc entity-framework ef-code-first user-permissions

我们有一个现有的工作系统,我被要求改变向用户提供“权限”的当前逻辑。目前的逻辑不太合适,就性能而言,它太慢了。

当前结构

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

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

问题

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

因此,当我们注册用户时,我们可以选择权限,例如user1只能从国家/地区表中读取国家/地区记录,只能从城市表中添加或编辑城市,只能从宗教表中删除宗教信息。

另外,系统有125种不同的角色。例如CountryCreateCountryDeleteCityCreateCityDelete等等。

在用户注册期间,系统会根据检查的值将不同的角色关联到用户。因此,假设管理员想要向用户提供70个权限,则70个角色将与该特定用户相关联,因为有许多用户需要数千个UserRoles。如果用户具有特定角色,则创建角色以检入视图,然后显示特定功能,例如国家创建,否则不显示。

应用程序大多数时间都停止工作。因为每个用户都有很多角色和复选框。

我是该项目的新手,第一项工作是更改权限逻辑。实现它的最佳方法是什么?

当前代码

if (model.countryRead == true)
{
  var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
                    userManager.AddToRole(user.Id, "countryRead");
}

所以,像这样我们有125 if statements,它只适用于Register。在编辑中,如果复选框为false,我们还会else statements从角色中删除。另外,我们在用户模型中有125个属性。

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

2 个答案:

答案 0 :(得分:1)

您可以遵循以下方法:

您已拥有UserRole型号。你只需要另一种具有这种结构的模型:

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

使用此模型,您可以定义无限访问。 UsersRoles   每个Role都可以有很多UserAccess

之后,您必须像125 if statements一样手动检查或更好地使用它,如果您使用的是Web API,我建议您使用:

首先,您必须从AuthorizeAttribute类继承,并使用您的访问模型(例如UsersRolesUserAccesses进行自定义,并且您必须覆盖OnAuthorization方法如:

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() }
                                   }
                   );
             } 
        }
    } 

然后,您必须在Web API中使用此ControllersActions上方的此属性:

 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)
         {

         }
    }

我希望它会有所帮助。

答案 1 :(得分:0)

如果不了解您的项目结构是什么样的(或实际上存在瓶颈),提供建议很困难,但为了帮助解决性能问题,您可能至少要做5件事:

  1. 不使用5个boolean字段获取权限,而是使用单个按位int字段,并将值转换为UI上的5个复选框。例如,1=access;2=create;4=read;8=update;16=delete,因此如果字段的值为13,则用户将具有访问权限,读取权限和更新权(1 + 4 + 8 = 13)。
  2. 目前还不清楚为什么每个表都有一列。为每个表创建一行更有意义,然后您可以拥有一列权限。
  3. 两个&#34;复选框&#34;听起来有点过分。和#34;角色&#34;。如果您的每个角色都是权限,那么您可以取消&#34;权限&#34;完全是一张桌子。
  4. 您可以使用System.Runtime.Caching.MemoryCache在内存中缓存权限(和/或角色),从而显着提高性能。
  5. 确保您的角色/权限不会保留在Cookie中,因为这意味着每个HTTP请求是一个页面,图像,CSS文件等将发送cookie往返,这可以翻译大量额外的网络流量字节。
  6. 权限表

    不确定为什么客户&#34;想要表&#34;。也许他们想要数据(已经作为角色存在),这就是你解释它的方式。您的首选应该是消除数据重复并只使用角色(因为MVC可以随时使用角色)。

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

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

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