Announcement Announcement Module
No announcement yet.
Voter based on method attribute Page Title Module
Move Remove Collapse
This topic is closed
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Voter based on method attribute

    First of all thanks to Ben! With is help I have been able to get a very basic Method Invocation security implemented in AppFuse:

    Now that I got that to wiggle, it is time to get to the real goal of this venture. I want to be able to limit access to UserManager.saveUser based on the object being passed to the method. In other words I want my users to be able to update their own account, but no one elses [except the admin, but that I will allow with a RoleVoter].

    But now that I'm looking closer at the existing voter code, I'm not sure if what I want to do is even possible without changing the way the UserManager works. Right now the only way I can see making this work is to have a UserManager.setUser(User user) method and then a UserManager.saveUser(). Then when I intercept the saveUser method, I can look up the user Object that was added to the secured object before the save method was called.

    Is there a way to access the parameters of a secured method?


  • #2
    I think I am approaching this the wrong way... I'm going to look more at the ACL examples and see if they do what I need [I'm pretty sure they do the more that I think about it].


    • #3
      The ACL package is are a very comprehensive answer to almost every domain object related security use case you can picture. I'd certainly encourage its use, given it's a "cool feature" :-)

      Having said that, though, it might be easier to write a custom AccessDecisionVoter. If you take a look in the reference guide, it discusses at the start of the ACL section the various approaches available to securing a domain object, and their pros and cons:


      • #4
        So Matt Raible said he was not interested in including ACL in the core of AppFuse, because it is not needed for all apps [which I agree with]. So to make the service layer security more complete without using ACL I created a new AccessDecisionVoter that compares the authenticated user's username to the returned value of a method call on a secured domain object. For example "Fred" can only perform UserManager.updateUser(user), when "user.getUsername()" returns "Fred".

        [You can check out more about what I did at ]

        This works and at least *I* think it is pretty cool, but now I want more

        What I want is to be able to divide my users into "groups" and to secure my objects so that only members of that group have access to them. Using what I have learned so far I can do everything that I need to make this happen except I don't know how to retreive the authenticated user's group name from the Authentication object.

        My thought was that it would be cool store my User bean as the UserDetail rather than the User that is provided by the jdbcDaoImpl, but I'm not sure what would be needed to make that happen. Can you help me figure out the best way to do that [or tell me why that is a dumb idea ]



        • #5
          You'd write a GroupAwareUser which extends User. Your AuthenticationDao would need to return the GroupAwareUser to its loadUserByName(String) method. If you're using JdbcDaoImpl, you'd need to override UsersByUsernameMapping such that it creates the GroupAwareUser instead of User. Your custom role voter would then merely cast Authentication.getPrincipal() to GroupAwareUser, where you'd have some method like getGroup().


          • #6

            After looking at more of the source code, I was headed down a path very similar to the one you described [heh, I guess I'm getting this stuff ].

            But then I had an idea and I think I may try to make something a bit more generic. I was thinking about using any Spring defined DAO bean [that implements AuthenticationDao and provides beans that implement UserDetail] rather than loading from JDBC directly. Then my Voter could be configured to call any method on that bean using reflection and compare its value to any method on the secured domain object [as defined in the configuration].

            Buf if I get stuck anywhere along those lines I may end up doing exactly as you suggest. If I do suceed in making something cool I'll be sure and see if you want it

            Thanks again,


            • #7
              Sounds an interesting approach!