我相信这是一个比其他任何事情都更好的关于最佳实践和设计的问题。我尝试搜索有关此类似的查询,但找不到任何。我实际上找到了Row Level Security with Entity Framework,但我相信这里的背景有点不同。实现行级安全 - (SPs vs LINQ to Objects)
我会尽量先解释一下我的情况:
我有一个使用一个共同的业务库来访问我的SQL通过NHibernate的2008和数据库在.NET 3.5网页。所有代码都是C#,使用NHibernate 2.1。 My WebSite显示来自业务库的不同IList的负载,业务层通过NHibernate获取来自SQL的所有数据。所以,因为我可以有一个方法返回IList,返回IList,另一个IList等...... 关键是活动用户只能访问所有返回的部分内容(几乎所有类型的结果集都必须从安全性),所以我需要在库上实现一个“数据过滤器”,它只会将允许的数据行返回给WebSite。为了实现这一点,我的网站上的IPrincipal被用于库中,这样我就可以获取用户的详细信息来过滤数据,但是由于我们的安全模型非常复杂,因此将其覆盖到我们所有的方法上会造成巨大的维护问题。 因此,为了解决这个问题,我们创建了几个SQL SP,它们返回当前用户所允许的项目以及我们只需要将所请求的数据与安全数据连接起来的业务逻辑,并且我们有最终结果集发送给用户。 现在,这个连接数据的过程是使用Linq到对象,我加入一个列表(安全)的iList,只返回允许的结果集。它可以通过GetAll()方法,ICriteria.List()或IQuery.List()或者甚至是NamedQuery.List()以及来自一个NamedQuery.List()的安全数据两个NamedQuery.List()。我也计划实现线程来同时允许两个SQL调用,并且在两个IList上执行LINQ连接之后,thread.join()。 我添加了一个示例代码,以说明如何执行一个方法。
第二个选项,这是我们试图摆脱的是在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>();
}
现在我的问题,这是行级安全可怕的方法/实践(请记住,我们的安全模型是非常复杂的,可定制的 - 这是业务设计),或者我们移动在正确的方向?我们可以选择其他选择吗?
由于提前, 克莱顿
嗨,谢谢你的回应。是的,这是一个很好的选择,但我的应用程序用户不是数据库用户,所以我需要以某种方式将我的用户ID发送到视图,而不能使用通用的NHibernate功能。我的问题不是太多访问数据库,而是访问应用程序本身。无论如何,我正在实施一个测试应用程序,看看我能否以某种方式在应用程序上放置此选项。 再次感谢。 – 2009-10-15 13:07:54
归结为SecurityBase.GetAllowedItemsForCurrentUser如何获取列表/它背后的逻辑是否可以轻松放入视图中,而不需要联合ID。 – Andrew 2009-10-15 13:30:12