Hibernate version: 3.0.x
I'm implementing security in an application and wanted to know the best way to use hibernate.
A high level view of our scenario is that there is a tree of domain objects (about 40 different object types) and a user can see either all or none of that hierarchy depending on their relationship with that hierarchy. We have two ways to access the data, both are stand alone J2EE apps using hibernate. One of the apps is a reporting tool that will make ad hoc queries to our database via hibernate (using hql) but currently has no notion of our security requirements. It will produce HQL code like 'select a.name, b.name from a inner join b on b.id = a.id'
I wanted to secure access to the database by using hibernate to limit what data is returned since hibernate is our common interface to the datbase. I also wanted security to be as transparent as possible so that our application developers don't have to manually add security to each of their queries. The problem is that I'm not sure of the technique to use.
The choice seems to boil down to filters & listeners or custom query translators.
when I have a querty from the j2ee app like
Code:
select a.name, b.name from a inner join b on b.id = a.id
I need it to go to the database looking like
Code:
select a.name, b.name from a inner join b on b.id = a.id
where a.org_unit in (1, 2, 3) and
b.org_unit in (1, 2, 3);
I was going to make a seperate filter for each object type (i.e. a, b, c, e, etc) and dynamically add the filter to the query depending on the objects that were being queried (in the example I gave, a and b). But the problem here is three fold
- I want to modify the query before it goes to the database so that results that are not needed are not returned, but I can't see where to do that. Interceptors and queries seem to occur after the database is hit and I'm worried that by doing the filtering post read that it will have a significant performance overhead.
- knowing which objects to filter on seems difficult as interceptors and events give you access to a single entity rather than the HQL
- As strange as this seems, I can't find the listener to extend for ad hoc queries
The alternative approach seems to be to create my own QueryTranslatorFactory which instantiates my own QueryTranslator that modifies that AST in the doCompile() method to add in a where clause. This seems a quite a drastic approach, but achievable. My problem here is that I don't know how to modify the AST to add in new where clauses.
Does anyone with experience in these matters have any words of wisdom?
Thank you for getting this far.
Mark