代码之家  ›  专栏  ›  技术社区  ›  Jay

保护/省略NHibernate中域实体的选定属性(子类,投影,?)

  •  2
  • Jay  · 技术社区  · 15 年前

    考虑以下简化场景:

    public class Person
    {
        public string Name { get; set; }
    
        public int Age { get; set; }
    
        // restricted
        public string SocialSecurityNumber { get; set; }
    
        // restricted
        public string MothersMaidenName { get; set; }
    }
    

    Person 数据。一些用户可以查看全部;其他用户只能查看 Name Age

    让UI只显示授权的数据在客户端是很容易的,但是我真的不想把这些数据发送到客户端。

    FullPerson : BasicPerson 层次结构(每个类层次结构的表)。我使用了 StaffRepository 获取所需的类型,但由于NH代理,必要的强制转换在运行时失败。当然,在RDBMS中 People FullPerson 或者 BasicPerson

    我只考虑了地图 全人 以及使用 AliasToBean

    我的另一个想法是将所有受限字段包装到一个类中,并将其作为属性添加。我对这种方法的担忧有几个:

    1. 我必须将该属性声明为一个集合(始终为1),以便延迟加载它,并且
    2. 我甚至不知道该如何阻止那个懒散的集合加载。

    所有这些感觉都不对。是否有一个已知的方法来实现预期的结果?

    澄清:

    这是在一个仅限于intranet的桌面应用程序中进行的;会话位于客户机上。虽然我当然可以创建一个中间服务层,但我必须放弃延迟加载和更改跟踪,这是我非常希望保持的。

    2 回复  |  直到 5 年前
        1
  •  2
  •   KeithS    15 年前

    首先,我要说的是,我不认为NHibernate有责任处理安全问题,而且数据编校基于同样的原则。我认为你试图把它放在数据访问层,这太复杂了。

    if(!user.CanSeeRestrictedFields)
       var results = from p as Repository.AsQueryable<Person>()
       //rest of Linq statement
       select new Person { 
             Name = p.Name,
             Age = p.Age
          };
    else
       var results = from p as Repository.AsQueryable<Person>()
       //rest of Linq statement
       select new Person { 
             Name = p.Name,
             Age = p.Age,
             SocialSecurityNumber = p.SocialSecurityNumber,
             MothersMaidenName = p.MothersMaidenName
          };
    

    我不知道Linq2NH是否足够聪明,可以将条件运算符解析为SQL;我对此表示怀疑,但有可能,您可以根据用户是否有权查看它们,在SSN和MMN字段的初始值设定项中指定条件运算符,从而允许您将这两个查询组合起来。

        2
  •  2
  •   DanP    15 年前

    我会留下你的域模型,而不是使用 Automapper

    编辑:

    proxy pattern CSLA.NET 对字段级安全性使用这样的方法,因此可能值得浏览源代码以获得一些启示。您也许可以更进一步,使用代理实现的接口,只公开用户有权访问的属性。