【问题标题】:Rhino.Security: second-level cache is never hit for DetachedCriteriaRhino.Security:DetachedCriteria 永远不会命中二级缓存
【发布时间】:2011-06-27 03:31:12
【问题描述】:

我已经实施了一个解决方案,其中涉及 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) 时,这种特殊情况的缓存才有效。 有没有人可以帮助我弄清楚发生了什么?

更新:

【问题讨论】:

  • 您是否在配置中启用了查询缓存? true

标签: asp.net-mvc nhibernate second-level-cache rhino-security


【解决方案1】:

此框架存在问题。 我在Google Groups上开了个题,大家都知道了,不过好像框架忘记了。

【讨论】:

    【解决方案2】:
    1. 确保您在事务中进行工作
    2. 验证 Permission 实体是否也被缓存

    【讨论】:

    • 感谢迭戈的帮助。我已经更新了我的问题。我附上了一张来自 NHProf 的图片。我参加了会议。如您所见,2 个选定的查询在事务中,但从未缓存。我加载了一个用户,它被缓存了。
    猜你喜欢
    • 2014-09-09
    • 2023-04-02
    • 2020-10-25
    • 2019-05-13
    • 1970-01-01
    • 2010-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多