我认为这不仅仅是关于最佳实践和设计的问题。我试图搜索有关此问题的类似查询,但找不到任何问题。我实际上找到了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>();
}
现在我的问题,对于行级安全来说这是一种糟糕的方法/做法(请记住,我们的安全模型非常复杂且可定制 - 这是通过业务设计),或者我们是否朝着正确的方向前进?我们可以选择其他任何选项吗?
提前致谢, 克莱顿
答案 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)
答案 2 :(得分:0)
作为一个选项,您是否考虑过不使用SQL SP返回允许项列表,而是在视图中使用相同的逻辑/连接,并仅查询视图/仅提供视图的权限,而不是基础表。