Filtering Linq to Nhibernate queries with Rhino Security 

Rhino Security provides the ability to filter NHibernate queries based on permissions. To do this, an IAuthorizationService interface is provided, that can be used in the following way:

var criteria = DetachedCriteria.For<Company>();
AuthorizationService.AddPermissionsToQuery(currentUser.Value, "/Company/View", criteria);
return criteria.GetExecutableCriteria(Session).List<Company>();

This way, a user only gets to see the companies he has permissions for. The AddPermissionsToQuery method expects a user, an operation and an NHibernate ICiteria object. The ICriteria object is the NHibernate Criteria that needs to be extended with permissions.

This works really well, a nice optimized query is generated. However, when working with Linq-to-Nhibernate, you don’t have an ICriteria object, so how can we add the permissions to those queries?

To figure this out, I downloaded the latest sources for Linq-to-Nhibernate and discovered a QueryOptions property on the INhibernateQueryable interface, which returns a QueryOptions type. The QueryOptions type provides a RegisterCustomAction method, which takes a parameter of the the type Action<ICriteria>, this looks hopeful.

By doing some tests, I found out that internally Linq-to-Nhibernate translates linq queries into a Criteria object. The RegisterCustomAction method allows us to perform custom actions on this criteria object, making it possible to add our own restrictions, excellent!

Integrating Rhino Security with Linq-to-NHibernate then gets us the following code:

INHibernateQueryable<User> query = Session.Linq<User>();
query.QueryOptions.RegisterCustomAction(x=>
          AuthorizationService.AddPermissionsToQuery(user, "/User/View", x));
return query.ToList<User>();

This results in the same query as the one resulting from the DetachedCriteria scenario. So this way you can have Rhino Security filter your queries based on permissions and still use Linq-to-Nhibernate.

Posted on 05-10-2009 by Jonne Kats
1 Comments  |  Trackback Url  |  Link to this post
Tags:

Links to this post

Comments

04-02-2010 by Kurt Johnson

You, sir, are a steely-eyed missile-man (oh: movie quote from "Apollo 13"). This is exactly what I have been search for. I see that NHibernate has an Interceptor. Creating an Interceptor for applying this on all of my entities seems like a desirable next step.

 
Name:
URL:
Email:
Comments:

CAPTCHA Image Validation