我正在尝试使用NHibernate实现权限,我想要做的是,每次有一个Select查询,检查返回类型是什么,以及它是否是一个安全启用类型(如发票)我想要向ICriteria对象添加限制,限制仅检索某些记录(如果用户已读取所有记录,或者读取自己的权限)。
我设法使用
为插入和更新实现这些权限NHibernater.Event.IPreUpdateEventListener
NHibernater.Event.IPreInsertEventListener
但不幸的是,在查询数据库之后调用了IPreLoadEventListener
,因此过滤将在计算机上本地完成,而不是由数据库完成。
有人知道NHibernate是否提供了某种在执行查询之前调用的事件吗?
答案 0 :(得分:2)
使用过滤器无法实现这一目标吗?
可以找到更多信息here
我在我的一个项目中将它与拦截器结合使用:
我有一些实体,每个用户都可以从中创建实例,但只有创建实例的用户应该能够查看/修改这些实例。其他用户无法看到用户X创建的实例。
为此,我创建了一个接口IUserContextAware
。 “用户上下文感知”的实体实现此接口。
在构建会话工厂时,我创建了必要的过滤器:
var currentUserFilterParametersType = new Dictionary<string, NHibernate.Type.IType> (1);
currentUserFilterParametersType.Add (CurrentUserContextFilterParameter, NHibernateUtil.Guid);
cfg.AddFilterDefinition (new FilterDefinition (CurrentUserContextFilter,
"(:{0} = UserId or UserId is null)".FormatString (CurrentUserContextFilterParameter),
currentUserFilterParametersType,
false));
完成后,我需要定义其他过滤条件:
foreach( var mapping in cfg.ClassMappings )
{
if( typeof (IUserContextAware).IsAssignableFrom (mapping.MappedClass) )
{
// The filter should define the names of the columns that are used in the DB, rather then propertynames.
// Therefore, we need to have a look at the mapping information.
Property userProperty = mapping.GetProperty ("UserId");
foreach( Column c in userProperty.ColumnIterator )
{
string filterExpression = ":{0} = {1}";
// When the BelongsToUser field is not mandatory, NULL should be taken into consideration as well.
// (For instance: a PrestationGroup instance that is not User-bound (that can be used by any user), will have
// a NULL value in its BelongsToUser field).
if( c.IsNullable )
{
filterExpression = filterExpression + " or {1} is null";
}
mapping.AddFilter (CurrentUserContextFilter, "(" + filterExpression.FormatString (CurrentUserContextFilterParameter, c.Name) + ")");
break;
}
}
现在,每当我实例化ISession
时,我都会指定应该使用某个拦截器:
此拦截器确保填充过滤器中的参数:
internal class ContextAwareInterceptor : EmptyInterceptor
{
public override void SetSession( ISession session )
{
if( AppInstance.Current == null )
{
return;
}
// When a User is logged on, the CurrentUserContextFilter should be enabled.
if( AppInstance.Current.CurrentUser != null )
{
session.EnableFilter (AppInstance.CurrentUserContextFilter)
.SetParameter (AppInstance.CurrentUserContextFilterParameter,
AppInstance.Current.CurrentUser.Id);
}
}
}
答案 1 :(得分:2)
如果您能够使用它,请查看Rhino.Security它完全符合您的要求。即使你无法使用它,你也可以看到他对这个问题的实现。