使用EF在MVC4中实现公司,部门,部门用户访问控制

时间:2013-03-02 13:17:40

标签: asp.net-mvc entity-framework multi-tenant access-control

这是我关于stackoverflow的第一个问题,所以请保持温和。我正在使用MVC4,Entity Framework和SimpleMembership为仓库应用程序编写客户门户。仓库托管多家公司的内容。每个公司都有部门和部门。用户将拥有对其公司,部门和部门的信息的不同访问权限。我正在寻找一种优雅的访问控制解决方案。到目前为止,我的模型看起来像这样:

public class UserProfile
{
    UserProfile()
    {
        this.AccessControl = new HashSet<AccessControl>();
    }

    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }
    public string UserName { get; set; }
    public Nullable<int> CompanyId { get; set; }
    public virtual ICollection<AccessControl> { get; set; }
    public virtual Company Company { get; set; }
}

public class AccessControl
{
    public int AccessControlId { get; set; }
    public int UserId { get; set; }
    public int CompanyId { get; set; }
    public Nullable<int> DivisionId { get; set; }
    public Nullable<int> DepartmentId { get; set; }
    public Boolean ReadAccess { get; set; }
    public Boolean WriteAccess { get; set; }

    // other properties for access control

    public virtual UserProfile UserProfile { get; set; }
    public virtual Company Company { get; set; }
    public virtual Division Division { get; set; }
    public virtual Department Department { get; set; }
}

public class Content
{
    public int ContentId { get; set; }
    public int CompanyId { get; set; }
    public int DivisionId { get; set; }
    public int DepartmentId { get; set; }

    // Various other properties

    public virtual Company Company { get; set; }
    public virtual Division Division { get; set; }
    public virtual Department { get; set; }
}

我的想法是NULL分区意味着所有分区而NULL分区意味着所有分区。我的问题是:

  1. 编写存储库方法以根据用户的访问控制列表检索内容对象列表以及在CRUD视图中填充部门和部门选择列表的优雅方法是什么?
  2. 是否有更好的方法来建模此访问控制列表?

2 个答案:

答案 0 :(得分:0)

我认为这还没有解决您的所有问题,但我认为存储库看起来像这样:

public class accessRepository
{
    accessContext context = new accessContext();

    public IQueryable<Content> GetAccessibleContentFor(int userId)
    {
        var up = context.UserProfiles.Single(u => u.UserId == userId);
        var companyId = up.CompanyId;

        return from c in context.Content 
               where c.CompanyId == companyId 
               && (up.AccessControl.Any(
                    a=> 
                        a.CompanyId == c.CompanyId && 
                        a.DivisionId == c.DivisionId && 
                        a.DepartmentId == c.DepartmentId) 
               || up.AccessControl.Any(
                    a=>a.CompanyId == c.CompanyId && 
                        a.DivisionId == c.DivisionId && 
                        a.DepartmentId == null)
               || up.AccessControl.Any(
                    a=>
                        a.CompanyId == c.CompanyId && 
                        a.DivisionId == null)
               select c;
    }
}

允许您在以下情况下获取可访问的内容:

  1. 内容属于用户的公司。
  2. 用户可以访问公司,部门和部门的内容
  3. 或者用户可以访问公司和部门(所有部门)的内容
  4. 或者用户可以访问公司(所有部门)的内容[在这种情况下假设所有部门。]

答案 1 :(得分:0)

您应该查看基于策略和属性的解决方案,该解决方案独立于您的应用,您可以在其中编写授权策略,例如:

如果content.department == user.department&amp;&amp;&amp; content.company == user.company。

XACML听起来就像是完美的模特。我写了这个演示,我根据购买者,数量,位置和PO的状态对采购订单进行访问控制。我不需要更改应用程序代码,因为我在外部使用XACML。