Issue Details (XML | Word | Printable)

Key: SEC-602
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Ben Alex
Reporter: Simon van der Sluis
Votes: 0
Watchers: 2
Operations

If you were logged in you would be able to see more operations.
Spring Security

Acl (Acls) class ObjectIdentityRetrievalStrategyImpl doesn't work well with proxied objects

Created: 14/Nov/07 03:37 PM   Updated: 04/Apr/08 09:47 PM
Component/s: ACLs
Affects Version/s: 1.0.3
Fix Version/s: 2.0.0

Time Tracking:
Not Specified

File Attachments: 1. Java Source File ProxyAwareObjectIdentityRetrievalStrategy.java (3 kB)
2. Java Source File ProxyAwareObjectIdentityRetrievalStrategyTest.java (6 kB)

Environment:
ubuntu gusty, Java HotSpot(TM) Client VM (build 1.6.0_01-b06, mixed mode, sharing)
tomcat 5.5.16
Issue Links:
Depends
 


 Description  « Hide
When using the AclEntryAfterInvocationProvider to check acl access on an object which has been instantiated by (in my case) hibernate, it is possible that hibernate will return a cglib enhanced instance of the object (or it might not). When ObjectIdentityRetrievalStrategyImpl then attempts to create an ObjectIdentity for it, that class name it gets is something like "com.mycompany.Foo$$EnhancerByCGLIB$$beb2e4f5", which does not match up with the class reference in the ObjectIdentity database record which is "com.mycompany.Foo", and no corresponding ACL entries will be found for the object.

I've found a couple of solutions for this, the first is to deproxy the object immediately after the query using a method something like:

public static Object deproxy(Object obj)
  {
    Hibernate.initialize(obj);
    
    if (obj == null)
    {
      return null;
    }
    
    if (HibernateProxy.class.isInstance(obj))
    {
      HibernateProxy proxy = (HibernateProxy) obj;
      return proxy.getHibernateLazyInitializer().getImplementation();
    }
    
    return obj;
  }

NOTE: Hibernate.initialise(object) doesn't work, because although it may flesh out the proxied object, it returns void, so we are still left holding onto the proxy.

I don't particularly like this approach, because for every factory method we need to remember to deproxy the found object, and where collections are returned, we'd need to deproxy every object in the collection.

An alternative solution is to write a ProxyAwareObjectIdentityRetrievalStrategy implementation. This is feasible because all (I think) classes that use an ObjectIdentityRetrievalStrategy support dependency injection.

I've had a go at this, and got the cglib enhanced case taken care of, but I also thought that the case where a Jdk proxy is returned needs to be addressed also. I've found a simple way to detect a Jdk proxy, but cannot figure how to get the class name we actually want out of it, as Jdk proxies only work on interfaces, and it's the InvokationHandler that does all the delegation.

class and tests will be attached.


 All   Comments   Work Log   Change History   FishEye   Builds      Sort Order: Ascending order - Click to sort in descending order
Simon van der Sluis added a comment - 14/Nov/07 03:42 PM
ProxyAwareObjectIdentityRetrievalStrategy and tests.

NOTE: You'll have to add
    <dependency>
      <groupId>cglib</groupId>
      <artifactId>cglib</artifactId>
      <version>2.1_3</version>
      <optional>true</optional>
    </dependency>

to the core pom.xml for these to compile and test


Ben Alex added a comment - 04/Apr/08 09:47 PM
Modified ObjectIdentityImpl to use Spring's ClassUtils class, which correctly extracts the underlaying superclass from a CGLIB enhanced version. SVN check-in revision 2858. Tests pass.