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). Есть ли кто-нибудь, кто может попытаться помочь мне выяснить, что происходит?

ОБНОВИТЬ:

2 ответа

Решение

Есть проблема с этой структурой. Я открыл вопрос по группам Google, все знают об этом, но кажется, что фреймворк был забыт.

  1. Убедитесь, что вы делаете работу внутри транзакции
  2. Убедитесь, что объект разрешения также кэшируется
Другие вопросы по тегам