In a nutshell, the idea is to extend the Session to include a javax.security.auth.Subject object. The Subject will never be null, but if it's not set it defaults to the current Subject. The public Session methods would then look something like
protected AccessControllerContext ctx = null;
public Object foo(Object o) throws HibernateException {
final Object fo = o; final Securitymanager sm = (System.getSecurityManager() == null) ? new SecurityManager() : System.getSecurityManager();
Subject.doAsPrivileged(subject, new PrivilegedExceptionAction() { public Object(run) throws HibernateException { // existing code goes here, uses 'fo' instead of o } }, ctx); }
This other side of this lives in Interceptors, e.g, a generic Interceptor to perform class and instance-level access control would look something like:
// "action" is "load", "save", "update", "delete"... private void check( String className, String action, Object entity) throws CallbackException {
String name = this.getClass().getName(); SecurityManager sm = System.getSecurityManager(); if (sm != null) try { // perform class-level access control sm.checkPermission( new TablePermission(name, className, action));
// perform instance-level access control if (entity != null) { sm.checkPermission( new RowPermission(name, className, action, entity)); } } catch (SecurityException e) { throw new CallbackException(e.getMessage(), e); } }
and you could perform owner/owned checking with an "owner" Permission, etc., whatever the application needs. Somebody will have to do some "magic" to write the Interceptor, but once that's done access control will be transparent to developers.
If the application is run directly by the user, we don't need to modify Session. But if the application is run on a server that uses JAAS for authentication, the Subject of the application is almost certainly different than the Subject making a request and we need to run as the client's Subject for JAAS access control to work.
It isn't hard to write a Session wrapper that implements this... but it puts the burden on the application writer to add it. (The same is true with the Interceptors, of course, but it's a more natural process since the designer has to write a fair amount of code for their own permissions.) It would be much nicer if we could hide this behind the SessionFactory with two new methods:
static Session openSession(Subject); static Session openSession(Subject, Interceptor);
(I don't see any need to have the ability to change Subject within a single Session.)
I know this looks nasty, but the gory details can be hidden and it then dramatically simplifies your code. Your methods no longer have to perform complicated checks, they just construct one or more Permissions that they require for access and make one quick call to the security manager. If it didn't throw an exception, they perform the action.
BTW, once we have this there are two obvious extensions - if the code mentioned earlier is 2.2 stuff this is 2.3 (or later). The first is to tie it into JCA.
The second is to store our Policy - this is what tells the AccessController what Permission each Subject has. The standard Policy is stored in a text file, and one variant uses XML... but d'oh we're sitting on top of a relational database! At a minimum there should probably be a new PermissionType that understands a PersistentObjectType or something like that - we need to be able to support mappings like
<permission name="com.example.security.TeacherPermission"> <property name="student" class="com.example.beans.Student"/> <property name="teacher" class="com.example.beans.Teacher"/> <property name="subject" type="string"/> <actions> <action name="instruct"/> <action name="tutor"/> <action/> </permission>
Eating our own tail, we also need to have permissions to CRUD other permissions. E.g., a PrincipalPermission would have permission to set or clear "actions" in a TeacherPermission, an AdminPermission would have permission to create or destroy AdminPermissions for other users, etc.
So... is somebody working on this? Should I try modifying SessionFactory and the default implemention (if I can ever find it)? I convinced my boss that it's worthwhile for me to invest some time in this and donate it to the project if it's something that others will find useful enough to ensure it will maintained in future versions - that's always far easier to do than wrapping code or applying patches.
Bear
------------------------------------------------------- This sf.net email is sponsored by:ThinkGeek Welcome to geek heaven. http://thinkgeek.com/sf _______________________________________________ hibernate-devel mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/hibernate-devel