【问题标题】:Implementing Row-Level Security – (SPs vs LINQ to Objects)实施行级安全性——(SP 与 LINQ to Objects)
【发布时间】:2010-12-07 00:01:33
【问题描述】:

我相信这更多是关于最佳实践和设计的问题,而不是其他任何问题。我尝试搜索与此相关的类似查询,但找不到任何查询。我实际上找到了Row Level Security with Entity Framework,但我相信这里的上下文有点不同。

我会先解释一下我的场景:

我有一个 .net 3.5 网站,它使用通用业务库通过 NHibernate 访问我的 SQL 2008 数据库。所有代码都是 C#,使用 NHibernate 2.1。 我的网站显示来自业务库的不同 IList 的负载,业务层通过 NHibernate 从 SQL 获取所有数据。因此,例如,我可以有一个返回 IList 的方法,另一个返回 IList、另一个 IList 等…… 关键是活动用户只能访问所有返回的一部分(几乎所有类型的结果集都必须从安全性中过滤),所以我需要在库上实现一个“数据过滤器”,它只返回允许的数据到网站的行。为了实现这一点,我的网站上的 IPrincipal 被用于库中,因此我可以获取用户详细信息来过滤数据,但由于我们的安全模型非常复杂,将其扩展到我们所有的方法会产生巨大的维护问题。 因此,为了解决这个问题,我们创建了几个 SQL SP,它们为当前用户返回允许的项目,在业务逻辑上,我们只需要将请求的数据与安全数据连接起来,我们就有最终的结果集要发送给用户。 现在这个加入数据的过程是使用 Linq to Objects 我加入一个带有列表(安全)的 iList 以只返回允许的结果集。 IList 通过不同的方式来自 NHibernate,可以是 GetAll() 方法、ICriteria.List() 或 IQuery.List() 甚至是 NamedQuery.List(),并且安全数据始终来自其中一个两个 NamedQuery.List()。我还计划实现线程以允许同时调用两个 SQL,并且在 thread.join() 之后在两个 IList 上执行 LINQ 连接。 我在下面添加了一个示例代码来说明如何执行一个方法。

第二个选项,这是我们试图摆脱的,是在 SQL 端实现 Join,让我们所有的调用都必须来自 SQL SP,它们将对安全结果进行连接,并且不允许业务完整使用 NHibernate 功能的代码。

public IList<Product> GetAllByName(string FirstLetter) {
    ICriteria GetAllCriteria = this.session.GetISession().CreateCriteria(typeof(Product));
    GetAllCriteria.Add(NHibernate.Criterion.Restrictions.Like("ProductName", FirstLetter));
    GetAllCriteria.AddOrder(NHibernate.Criterion.Order.Asc("ProductName"));

    // Here would go the Threading for the both calls
    IList<Guid> AllowedItems = SecurityBase.GetAllowedItemsForCurrentUser();
    IList<Product> AllProducts = GetAllCriteria.List<Product>();

    var ResultSet = from Prod in AllProducts
                    join Sec in AllowedItems on Prod.Id equals Sec
                    select Prod;

    return ResultSet.ToList<Product>();
}

现在我的问题是,对于行级安全来说,这是一种糟糕的方法/实践吗(请记住,我们的安全模型非常复杂且可定制——这是通过业务设计来实现的),还是我们正朝着正确的方向前进?我们还有其他选择吗?

提前致谢, 克莱顿

【问题讨论】:

    标签: c# security .net-3.5 linq-to-objects row-level-security


    【解决方案1】:

    我目前正在从事具有类似要求的项目。这是一个绿色项目,尚未编写任何代码,我们只是在寻找基于行的安全性的解决方案。

    我会推荐你​​这两篇文章:

    http://www.codeproject.com/KB/database/Modeling_DAGs_on_SQL_DBs.aspx http://www.codeproject.com/KB/database/AFCAS.aspx

    关于你的线程想法,使用 System.Threading 会让你伤心,看看 Ritcher 的 AsyncEnumerator 或 Microsoft Concurrency runtime (CCR)

    【讨论】:

      【解决方案2】:

      我知道这有点晚了,但您是否看过以下内容:

      http://securedata.codeplex.com

      这是一个开源项目,我是我的首席开发人员,它无缝地实现了行级安全性。

      【讨论】:

        【解决方案3】:

        作为一种选择,您是否考虑过使用相同的逻辑/在视图内部连接并仅查询视图/仅提供对视图的权限,而不是使用 SQL SP 返回允许的项目列表基础表。

        【讨论】:

        • 您好,感谢您的回复。是的,这是一个不错的选择,但我的应用程序用户不是 DB 用户,所以我需要以某种方式将我的用户 ID 发送到视图,并且无法使用通用的 NHibernate 函数。我的问题不是对数据库的访问,而是对应用程序本身的访问。无论如何,我正在实现一个测试应用程序,看看我是否可以以某种方式将此选项放在应用程序上。再次感谢。
        • 归结为 SecurityBase.GetAllowedItemsForCurrentUser 如何获取列表/背后的逻辑是什么,是否可以轻松地在视图中放置而不需要联合 ID。
        猜你喜欢
        • 2011-10-22
        • 1970-01-01
        • 2011-03-10
        • 2013-09-03
        • 2018-03-03
        • 1970-01-01
        • 2010-11-05
        • 1970-01-01
        • 2013-05-18
        相关资源
        最近更新 更多