asp.net-mvc – Rhino.Security:从不为DetachedCriteria命中二级缓存

我已经实现了一个涉及Rhino.Security的解决方案来管理用户/角色/权限.

由于我想检查用户是否有权访问控制器操作,因此我实现了自定义操作过滤器:

public class AuthorizationAttribute : ActionFilterAttribute
{
    CustomPrincipal currentPrincipal = (CustomPrincipal)filterContext.HttpContext.User;
    var actionName = filterContext.ActionDescriptor.ActionName;     
    var controllerName = filterContext.Controller.GetType().Name;
    var operation = string.Format("/{0}/{1}", controllerName, actionName);

    if (!securityService.CheckAuthorizationOnOperation(currentPrincipal.Code, operation))
    {
    filterContext.Controller.TempData["ErrorMessage"] = string.Format("You are not authorized to perform operation: {0}", operation);
    filterContext.Result = new HttpUnauthorizedResult();
    }
}

CheckAuthorizationOnOperation调用Rhino.Security来检查是否允许用户执行指定的操作:

AuthorizationService.IsAllowed(user, operation);

一切正常但我注意到,当执行IsAllowed调用的查询时,永远不会遇到二级缓存.
我已经调查过,我已经看到框架(Rhino.Security)使用了DetachedCriteria.这些是2个程序:

public Permission[] GetGlobalPermissionsFor(IUser user, string operationName)
{
    string[] operationNames = Strings.GetHierarchicalOperationNames(operationName);
    DetachedCriteria criteria = DetachedCriteria.For<Permission>()
        .Add(Expression.Eq("User", user)
             || Subqueries.PropertyIn("UsersGroup.Id",
            SecurityCriterions.AllGroups(user).SetProjection(Projections.Id())))
        .Add(Expression.IsNull("EntitiesGroup"))
        .Add(Expression.IsNull("EntitySecurityKey"))
        .CreateAlias("Operation", "op")
        .Add(Expression.In("op.Name", operationNames));

    return FindResults(criteria);
}

private Permission[] FindResults(DetachedCriteria criteria)
{
    ICollection<Permission> permissions = criteria.GetExecutableCriteria(session)
    .AddOrder(Order.Desc("Level"))
    .AddOrder(Order.Asc("Allow"))
    .SetCacheable(true)
    .List<Permission>();
    return permissions.ToArray();
}

如您所见,FindResults使用SetCacheable.

每次刷新页面时,我的动作过滤器都会执行过程,并再次执行查询,忽略缓存(第二级).
由于我广泛使用缓存和所有其他调用正常工作,我想了解为什么这个调用不能按预期工作.

做一些研究我注意到只有在我调用函数两次时才使用二级缓存:

SecurityService.CheckAuthorizationOnOperation(currentPrincipal.Code, "/Users/Edit");
SecurityService.CheckAuthorizationOnOperation(currentPrincipal.Code, "/Users/Edit");

看来这种特殊情况的缓存只有在我使用相同的会话(nHibernate)时才有效.
有没有人可以试着帮我弄清楚发生了什么?

更新:

最佳答案 >确保您在交易中完成工作

>验证Permission实体是否也被缓存

点赞