我相信这更多的是关于最佳实践和设计的问题。我尝试搜索与此相关的类似查询,但找不到任何查询。我实际上找到了带有实体框架的行级安全性,但我相信这里的上下文有点不同。
我将首先尝试解释我的情况:
我有一个 .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。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>();
}
现在我的问题是,对于行级安全来说,这是一种糟糕的方法/实践(请记住,我们的安全模型非常复杂且可定制——这是通过业务设计实现的),还是我们正朝着正确的方向前进?我们还有其他选择吗?
在此先感谢,克莱顿