Announcement Announcement Module
No announcement yet.
Using ACL and voters Page Title Module
Move Remove Collapse
This topic is closed
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Using ACL and voters

    I've been experimenting with the new ACL code in 0.6,

    I'm starting this topic to kind of explore the best practices for ACL usage, because the documentation only contains a simple reference to wiring up the AclManager to a Voter. It doesn't give much beyond that.

    What I have working so far is using the JdbcDaoImpl to retrieve a arry of ACLs for a domain/authorization object. A code snippet from one of my JUnit tests follows:

    AclEntry[] aclEntries = am.getAcls(testTopic, auth);
    assertEquals(1, aclEntries.length);
    But now what I want to do is actually have a Voter work on it. Is there a concrete implementation of a Voter I can use in 0.6, or do I need to write my own.. and if I do write my own, can you give me a guideline on what I should be doing. Should I be passing in the AclEntry array as part of the ConfigAttributeDefinition object? Then having the voter iterate through the AclEntry array to find a bit mask that gives the level of permission requried to return a 'yes' vote?

    Am I missing anything else here?

  • #2
    Your AccessDecisionVoter should be wired to the AclManager as a collaborator bean via the ApplicationContext. The Authentication need not contain any ACL details (ie there is no need to do anything with GrantedAuthority[]s contained within Authentication).

    You would probably write a custom AccessDecisionVoter which acts when a particular ConfigAttributeDefinition is detected. Take a look at the Contacts sample application's ContactSecurityVoter. You could refactor this to use the new ACL packages if you were willing to have a JDBC backend or write a BasicAclDao that provides an in-memory implementation (personally I'd favour the former, using in-memory Hypersonic, as per the Petclinic RCP sample).


    • #3
      sample app

      benalex: any plans to include a sample app in the next release that uses ACL's ?

      Great work BTW!


      • #4
        I've been making more progress on this area.. sometimes sleeping on something does work wonders in making things seem so much clearer in the morning.

        Anyway, what I'm doing here is actually building a quick proof-of-concept to ensure that Acegi's ACL can meet the requirements of our upcoming project. Since this code is mainly just a vertical slice, I see no problems with donating this code to the examples part of Acegi if you are interested.

        But obviously I need to figure out some more stuff.

        Right now I've got the ACL doing successful voting on a domain object, by calling a DecisionVoter (its a AffirmativeBased one) that's wired up with the AclVoter instance that I wrote up, and I pass in the authentication object, the domain object that it needs to vote on.

        Now what I'm trying to figure out is how to properly handle the MethodInterceptor process.

        Like say, if I have a domain object, of type Foo, and I want to do a call to the service layer to obtain a Foo object, of id# 200.

        SecureContext sc = new SecureContextImpl();
        Foo f = fooService.load(200);
        So, now I've placed an Authorization object in the SecureContext and attempt to invoke the .load() method. This is where I'm a bit fuzzy on what should happen.

        Should this be a two step process.. like writing a different kind of ACL voter that would simply check for read rights for the object passed in and vote to allow the method to happen? Then when passing the Foo object to the web layer, if I wanted to check to see if the user had edit privileges for the object, I'd need to run a different ACL voter that would check for edit-level rights for this object?

        Or am I missing something here?


        • #5
          I'm not sure which part of the process you're not sure of, so here's a quick summary....

          Typically you'd use the included filters to automatically populate the ContextHolder from a "well known location" in the container (more often then not HttpSession). Even so, you can still populate the ContextHolder directly using your own code if you prefer.

          The fooService should be obtained from the Spring application context, which should have fooService wired to load the MethodSecurityInterceptor (which is also defined in the application context). MethodSecurityInterceptor delegates to the AuthenticationManager to check the ContextHolder-presented credentials are valid, and then to the AccessDecisionManager. You're using AffirmativeBased which delegates to the list of AccessDecisionVoters. Each AccessDecisionVoter decides whether or not it is required by reference to the ConfigAttributeDefinitons which were defined against the MethodSecurityInterceptor. It then votes accordingly. The voter will typically be wired to the AclManager collaborator so it can obtain the applicable ACLs.