Results 1 to 9 of 9

Thread: Question about Users/Roles and ACL

  1. #1
    Join Date
    Nov 2005
    Location
    Atlanta
    Posts
    15

    Question Question about Users/Roles and ACL

    Hi,
    I have been reading a lot for the last couple of days about how Acegi Security supports authorization using users, authorities and ACLs.

    Some of the questions that I have are

    1) I assume that authorities is same as (or similar to) roles. Is this correct or am I missing something ?

    2) Considering that the ACLs will be on per object basis, I guess that the table(s) containing ACLs will grow as we add more data to the system. Are there any issues related to this approach ? Do we have to add data to this table as soon as a new object is created ? How do we manage this part ?

    For my current project, we do not need ACLs at this time and therefore I plan to start using a simpler scheme with users and roles (Granted Authority) objects. In case, we need to migrate to ACLs later, is this possible at all ?

    OR

    Can we use the ACL classes (ACLEntryVoter etc) but use roles under the covers ? Then, the changes when we switch to ACL will be within the implementation.


    Once again, thanks to the Acegi Security team for providing the software and the reference docs.

    Regards
    Mandar

  2. #2
    Join Date
    Nov 2004
    Location
    Hilversum - The Netherlands
    Posts
    1,054

    Default

    What is the problem you trying to solve?

    You want to make sure that a method-call is denied when the Role is valid, but the argument(s) isn`t valid?

    Eg:
    A registered user (has the role ROLE_REGISTERED) tries to update an item that doesn`t belong to him. The update method requires the role ROLE_REGISTERED, so he can proceed because he has the correct role, but he must not proceed because it isn`t his item.

    A conditional role: is this what you need?
    Last edited by Alarmnummer; Feb 8th, 2006 at 10:10 AM.

  3. #3
    Join Date
    Nov 2005
    Location
    Atlanta
    Posts
    15

    Question

    Hi,
    We are developing a system that has user structure such as

    SolutionOwnerOrg
    admin1, admin2 etc

    Org 1
    user11, user12, user55 etc
    Org 2
    user21, user22, user55 etc

    Right now, the requirements are

    1) any user in Org1 can create/update/delete any item that belongs to Org1 (self organization or organizations to which the user belongs). user55 can add/update/delete items in both orgs.

    2) any user in SolutionOwnerOrg can view/update/update any item in the system.

    Hope that I am clear.

    I am trying to figure out what is the best approach to use users/roles/ACLs so that I can extend it later as and when necessary.

    Note: We might need roles within an Org in the next phase of the project.

    Thanks for your help.

    Regards
    Mandar

  4. #4
    Join Date
    Nov 2004
    Location
    Hilversum - The Netherlands
    Posts
    1,054

    Default

    I have been playing with conditional roles as an replacement for ACL and we are running it in one of our projects and it works like a dream.

    I have created the following code to create a common understanding:
    Code:
    class Organisation{
    }
    
    class Item{
    	Organisation organisation;
    }
    
    class User{
    	Organisation organisation;
    }
    
    interface ItemManager{
    	void update(Item item);
    	void delete(Item item);
    	void create(Item item);
    }
    And this is an example of the configuration:
    Code:
    <bean id="itemManagerSecurityAdvice"
    	class="net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
    	<property name="validateConfigAttributes" value="true"/>
    	<property name="authenticationManager" ref="authenticationManager"/>
    	<property name="accessDecisionManager" ref="accessDecisionManager"/>
    	<property name="objectDefinitionSource">
    		<value>
    			ItemManager.create=ROLE_USER:arg0.organisation.equals(securityContext.user.organisation),ROLE_SOLUTION_OWNER
    			ItemManager.delete=ROLE_USER:arg0.organisation.equals(securityContext.user.organisation),ROLE_SOLUTION_OWNER
    			ItemManager.update=ROLE_USER:arg0.organisation.equals(securityContext.user.organisation),ROLE_SOLUTION_OWNER
    		</value>
    	</property>
    </bean>
    Every user with the role ROLE_USER is allowed to create/delete/update items as long as the condition arg0.organisation.equals(securityContext.user.orga nisation) holds.

    The org0 is the first argument of the methods (in all cases this is the Item you are trying to use). And you check if the organisation the item belongs to, is the same as the organisation of the logged in user (can be found in the securityContext).

    Every user with the role ROLE_SOLUTION_OWNER can do everything he likes without any condition.

    The user55 has the same roles as the admins? I haven`t added his constraints to the security.

    If you need something less static, ACL would be a better alternative.
    Last edited by Alarmnummer; Feb 8th, 2006 at 10:36 AM.

  5. #5

    Default Nice example

    Hi Alarmnummer,

    thank you for this nice example. I have a similar situation with conditional roles. There is one question, that I came up with.
    How would you realize security in case item has one organisation and user has a set of organisations, it belongs to? Could you solve the problem with your "way"?

    Thanks
    Lorelia

  6. #6
    Join Date
    Nov 2004
    Location
    Hilversum - The Netherlands
    Posts
    1,054

    Default

    Quote Originally Posted by lorelia
    Hi Alarmnummer,

    thank you for this nice example. I have a similar situation with conditional roles. There is one question, that I came up with.
    How would you realize security in case item has one organisation and user has a set of organisations, it belongs to? Could you solve the problem with your "way"?
    Code:
    class User{
        Set<Organisations> organisations;
    }
    
    class Item{
       Organisation organisation;
    }
    
    class Organisation{}
    
    interface ItemManager{
         void delete(Item item);
    }
    
    
    ItemManager.delete=ROLE_FOO:securityContext.user.organisations.contains(arg0.organisation);
    In some cases you don`t have direct access to the user his organisations (maybe this relation isn`t part of the java code, only in the db). So then you need something else like:
    Code:
    interface OrganisationDao{
         Set<Organisation> findByUser(User user);
    }
    
    ItemManager.delete=ROLE_FOO:organisationDao.findByUser(securityContext.user).contains(arg0.organisation);
    But at the moment it isn`t allowed to access dependencies from the ApplicationContext in the expression. But as you can see, there are very good reasons why this should be added. We are still playing with it..

    [edit]
    The expression is an OGNL expression. So you have a lot of freedom in creating your own conditions.
    Last edited by Alarmnummer; Feb 9th, 2006 at 06:51 AM.

  7. #7

    Default Implementation

    Thank you Alarmnummer!
    I implemented this by using OGNL and it works fine for me. I wrote my own roleVoter by extending RoleVoter. My vote() method does now check for an expression and evaluates it.

    Here is what my securityInterceptor looks like:
    ----------------------------------------

    <bean id="securityInterceptorAOP"
    class="org.acegisecurity.intercept.method.aopallia nce.MethodSecurityInterceptor">
    <property name="validateConfigAttributes">
    <value>true</value>
    </property>
    <property name="authenticationManager">
    <ref bean="authenticationManager"/></property>
    <property name="accessDecisionManager">
    <ref bean="accessDecisionManager"/></property>
    <property name="objectDefinitionSource">
    <value>
    de.test.bus.userman.UserServiceIF.registerUser=ROL E_SYSADMIN
    de.test.bus.project.ProjectServiceIF.deleteProject =ROLE_PROJECTADMIN:arg0.getUsersForProject().conta ins(@org.acegisecurity.context.SecurityContextHold er@getContext().getAuthentication().getPrincipal() ),ROLE_SYSADMIN
    </value>
    </property>
    </bean>
    ----------------------------------------

    I like to share my own roleVoter, but since it looks so ugly to copy and paste it, please have a look at the attachment. Any comments on this are appreciated.

    Greetings
    Lorelia
    Attached Files Attached Files

  8. #8
    Join Date
    Nov 2004
    Location
    Hilversum - The Netherlands
    Posts
    1,054

    Default

    Quote Originally Posted by lorelia
    Thank you Alarmnummer!
    I implemented this by using OGNL and it works fine for me. I wrote my own roleVoter by extending RoleVoter.
    It is nice to see we are using the same technique to introduce 'conditional roles'. I also have enhanced the RoleVoter, but I also have provided a custom version of the ConfigAttribute that now contains a Condition. The Condition is an interface and in this case I have added a OGNL implementation that contains the OGNL expression. You can also provide a different implementation, for example a Groovy version (but I haven`t implemented that one).

    my rolevoter looks like this:
    Code:
    public int vote(Authentication auth, Object object, ConfigAttributeDefinition config) {
    		int result = ACCESS_ABSTAIN;
    		Iterator iter = config.getConfigAttributes();
    
    		while (iter.hasNext()) {
    			ConfigAttribute requiredAttribute = (ConfigAttribute)iter.next();
    			if (this.supports(requiredAttribute)) {
    				result = ACCESS_DENIED;
    
    				// Attempt to find a matching granted authority
    				for (int i = 0; i < auth.getAuthorities().length;i++) {
    					String requiredRole = requiredAttribute.getAttribute();
    					String grantedRole = auth.getAuthorities()[i].getAuthority();
    
    					if (requiredRole.equals(grantedRole)) {
    						if(requiredAttribute instanceof MyConfigAttribute){
    							MethodInvocation mi = (MethodInvocation)object;
    							MyConfigAttribute myAttr = (MyConfigAttribute)requiredAttribute;
    							myAttr.getInvocationChecker().check(mi);
    						}
    						return ACCESS_GRANTED;
    					}
    				}
    			}
    		}
    
    		return result;
    	}
    <property name="objectDefinitionSource">
    <value>
    de.test.bus.userman.UserServiceIF.registerUser=ROL E_SYSADMIN
    de.test.bus.project.ProjectServiceIF.deleteProject =ROLE_PROJECTADMIN:arg0.getUsersForProject().conta ins(@org.acegisecurity.context.SecurityContextHold er@getContext().getAuthentication().getPrincipal() ),ROLE_SYSADMIN
    </value>
    </property>
    Looks almost the same. I have added the Context from the Acegi ContextHolder to the OGNL context so I don`t have to write so much code, but that is just some eyecandy.

    I would like to hear what your experiences are with this syntax. There are a few problems:
    1) you keep repeating expressions
    2) lines get long

    I would like to hear what you think that smells.

    I like to share my own roleVoter, but since it looks so ugly to copy and paste it, please have a look at the attachment. Any comments on this are appreciated.
    I hope conditional roles are introduced to ACEGI (and I hope being part of it).
    Last edited by Alarmnummer; Feb 10th, 2006 at 04:03 AM.

  9. #9
    Join Date
    Apr 2006
    Posts
    1

    Question

    I also have enhanced the RoleVoter, but I also have provided a custom version of the ConfigAttribute that now contains a Condition.
    How did you get acegi to create you're own MyConfigAttribute instead of regular 'SecurityAtrribute' ?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •