我们正在完全重写现有产品(并且正在从 PHP 更改为 C#)。我们在现有产品中遇到的问题之一是授权问题:除非您确保始终在任何地方进行检查,否则人们会看到他们不允许看到的内容。确保始终检查它的最佳位置是什么?我认为数据层是这样做的好地方,但欢迎提出其他建议。
我们使用 NHibernate,因此我们构建了一个提供实体的类。它看起来像这样:
class DataProvider {
TEntity Get<TEntity>(int id) {
return GetSession().Get<TEntity>(id);
}
IQueryable<TEntity> Query<TEntity>()
{
return GetSession().Query<TEntity>();
}
// ...
}
这允许我DataProvider.Get<Person>(1)
使用from person in DataProvider.Query<Person>() select person
. 使用拦截器将允许我拒绝访问用户无权访问的任何单个对象(尽管可以说我可以将该代码插入DataProvider.Get
)。当我尝试使用 LINQ 时,它变得很麻烦。假设我有一个包含 100 万个实体的表,但我只能访问 5 个实体。使用拦截器将检索整个表并测试每个返回的实体,但我只需要其中的 5 个。我能想象的最好的事情是注入一些自定义 SQL 来告诉 NHibernate 检索哪些对象并忽略所有其他对象。我们已经有一个系统可以确定我们是否可以访问一个对象,假设我们也知道如何从中进行查询。
我尝试了什么?
- 拦截器(为时已晚,只需要 5 个时检索 100 万个对象)。
- 事件(IPostLoadEvent 最接近我的需要,但也为时已晚)。
- 自定义 NhQueryable 和 DefaultQueryProvider。这会引发一个异常:“
The constant for 'MyQueryable<Person>' is not supported
”,我认为这是由于 NHibernate 内部某个深处的投射所致。我怀疑 NHibernate 的设计目的是允许自定义查询提供程序或可查询。 - OnPrepareStatement 拦截器。这是难以置信的丑陋。它允许我编辑 SQL,但我得到的只是一个字符串。这会起作用,但我希望有一种更优雅的方式来做同样的事情。
其他人如何处理他们的授权码?您如何确保没有人忘记调用授权检查?