Announcement Announcement Module
Collapse
No announcement yet.
Question about Users/Roles and ACL Page Title Module
Move Remove Collapse
This topic is closed
X
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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
    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, 10:10 AM.

    Comment


    • #3
      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

      Comment


      • #4
        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, 10:36 AM.

        Comment


        • #5
          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

          Comment


          • #6
            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, 06:51 AM.

            Comment


            • #7
              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

              Comment


              • #8
                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, 04:03 AM.

                Comment


                • #9
                  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' ?

                  Comment

                  Working...
                  X