Rhino.Security: кэш второго уровня никогда не срабатывает для DetachedCriteria - PullRequest
4 голосов
/ 14 февраля 2011

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

UPDATE: enter image description here

Ответы [ 2 ]

1 голос
/ 03 сентября 2012

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

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