Rhino.Security: L2 cache never gets into DetachedCriteria

I implemented a solution that includes Rhino.Security for managing users / roles / permissions.
Since I want to check if the user is allowed access to the controller’s action, I implemented a custom action filter:

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 calls Rhino.Security to check if the user is allowed the specified operation:

 AuthorizationService.IsAllowed(user, operation); 

Everything works correctly, but I noticed that the second level cache never gets when the request called IsAllowed is executed .
I researched and I saw that the environment ( Rhino.Security ) uses DetachedCriteria . These are two procedures:

 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(); } 

As you can see, FindResults uses SetCacheable .

Each time I refresh the page, my action filter executes the procedures, and the request is executed again, ignoring the cache (second level). Since I make extensive use of the cache and all other calls work correctly, I would like to understand why this one does not work properly.

After doing some research, I noticed that the second level cache is used only if I call the function twice:

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

It seems that the cache for this particular situation only works if I use the same session (nHibernate). Is there anyone who can help me figure out what's going on?

UPDATE: enter image description here

+4
source share
2 answers

There is a problem with this structure. I opened the question about Google Groups , everyone knows about it, but it seems that the structure has been forgotten.

+1
source
  • Make sure you do the work inside the transaction.
  • Make sure the Permission object is also cached.
+1
source

Source: https://habr.com/ru/post/1339716/


All Articles