4

这是我关于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 Division 表示所有部门,NULL Department 表示所有部门。我的问题是:

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

2 回答 2

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. 或者用户可以访问公司(所有部门)的内容[在这种情况下假定所有部门。]
于 2013-03-02T18:17:30.703 回答
0

您应该研究一个独立于您的应用程序的基于策略和属性的解决方案,您可以在其中编写授权策略,例如

如果 content.department==user.department && content.company==user.company,则用户可以访问仓库中的内容。

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

于 2013-03-03T04:08:24.490 回答