Reputation: 987
I'm attempting to coerce an existing NHibernate application into something like a multi-tenant application. The data model is fairly large (60+ entities) although only a small subset of these entities need to be secured. As an added wrinkle, the data access model is used in separate applications that should disregard security.
To that end, I've created further entities that represent an ACL on the securable entities.
I've managed to get something that looks like security by adding a LoadCollection listener. When a collection of secured entities is loaded, I check the ACL for each one and remove it from the list if access isn't allowed.
However, I can't figure out how to accomplish the same thing when loading a single entity. I have a PreLoad event listener and I'm able to determine if the caller has access. If they don't have access, I would like to return a null item. I've tried setting the entity associated with the event to null and evicting the entity from the session.
Documentation on using this event is pretty thin on the ground: Mostly it's events that fire before saving that have worked examples. The NHibernate Cookbook uses a very old version of NHibernate with a different signature for events (e.g. they return bool rather than the void of NHibernate 3.3.x).
Edit: After spelunking through the NHibernate source, I've determined that I was looking at the wrong Load event. I tried "PreLoad" and "PostLoad", not realizing that the plain old "Load" event was what I was after.
This has raised a new issue though: When loading an object that is not secured, but has a secured parent, my Load event listener will fire for the proxy of the parent. Eager-loading or not, the parent proxy won't have a correct ACL: It is coming up empty every time.
Upvotes: 1
Views: 609
Reputation: 1538
A good full example for a NHibernate application using this design can be found in NHibernate best practices, we're using it for a enterprise, heavy web application with more than 300 entities with big success. On top of that we implemented a context control mechanism, each end user is requesting a security token on log-in and use it on every sequential call, on every sequential call we check the security token for validation and use it to create an additional criterion that limit each user access depending on his\her configuration. It was a big project, but it gave us a good infrastructure for developing and maintenance.
Upvotes: 2