实现行级安全性 - (SPs vs LINQ to Objects)

时间:2009-10-15 11:13:16

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

我认为这不仅仅是关于最佳实践和设计的问题。我试图搜索有关此问题的类似查询,但找不到任何问题。我实际上找到了Row Level Security with Entity Framework,但我相信这里的背景有点不同。

我将首先尝试解释我的情景:

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

第二个选项,这就是我们试图摆脱的目的是在SQL端实现Join,让我们所有的调用都必须来自SQL SP,这些SQL会对安全结果进行连接而不允许业务用于完全使用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>();
}

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

提前致谢, 克莱顿

3 个答案:

答案 0 :(得分:2)

我目前正在开发一个具有类似要求的项目。这是一个绿色的现场项目,还没有编写代码,我们只是在寻找基于行安全性的解决方案。

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

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并发运行时(CCR)

答案 1 :(得分:2)

我知道这有点晚了但是你看了下面的内容:

http://securedata.codeplex.com

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

答案 2 :(得分:0)

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