Results 1 to 4 of 4

Thread: RoleHierarchy in GrantedAuthorities

  1. #1
    Join Date
    Mar 2010
    Posts
    12

    Default RoleHierarchy in GrantedAuthorities

    I'm using Spring Security 3.0.4.RELEASE and I'm trying to figure out if RoleHierarchy can be used when simply looping through granted Authorities. Below is my config:

    Code:
    <beans:bean id="webSecurityExpressionHandler" class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler">
            <beans:property name="roleHierarchy" ref="roleHierarchy" />
        </beans:bean>
    
        <!-- An expression handler used to secure methods.
             This overrides the DefaultMethodSecurityExpressionHandler to include roleHierarchy.
        -->
         <beans:bean id = "methodSecurityExpressionHandler" class = "org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
            <beans:property name = "roleHierarchy" ref ="roleHierarchy"/>
        </beans:bean> 
    
        <beans:bean id="roleHierarchy" class="org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl">
            <beans:property name="hierarchy">
                <beans:value>
    			ROLE_ADMIN > ROLE_MANAGER
    			ROLE_MANAGER > ROLE_USER
                            ROLE_USER > ROLE_AUTHENTICATED
    			ROLE_AUTHENTICATED > ROLE_UNAUTHENTICATED
                </beans:value>
            </beans:property>
        </beans:bean>
        
        
        <global-method-security pre-post-annotations="enabled" secured-annotations="enabled">
            <security:expression-handler ref="methodSecurityExpressionHandler"/>
        </global-method-security>
        
        <!-- security:authorize tags using the url attribute will delegate to this accessDecisionManager -->
        <beans:bean id="webAccessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
            <beans:property name="decisionVoters">
                <beans:list>
                    <beans:bean class="org.springframework.security.web.access.expression.WebExpressionVoter">
                        <beans:property name="expressionHandler" ref="webSecurityExpressionHandler" />
                    </beans:bean>
                </beans:list>
            </beans:property>
        </beans:bean>
    
        <http auto-config="true" use-expressions="true" access-decision-manager-ref="webAccessDecisionManager">
            <form-login login-page="/login" default-target-url="/"
                always-use-default-target="false"
                authentication-failure-url="/login?error=authorizationFailed" />
            <logout invalidate-session="true" logout-url="/logout"
                logout-success-url="/login?error=loggedOut" />
            <access-denied-handler error-page="/error?id=accessDenied" />
            <remember-me key="company-app-remember" />
            <!-- ... -->
        </http>
        <authentication-manager alias="authenticationManager">
            <ldap-authentication-provider
                user-search-filter="mail={0}" user-search-base="ou=people,o=company"
                user-context-mapper-ref="customUserDetailsContextMapper" group-search-base="ou=groups,o=company" />            
        </authentication-manager>
    So what I want to do is in my method check if the user is ROLE_MANAGER but if the user is ROLE_ADMIN then it should be included (as shown in the hierarchy). It doesn't seem that the granted authorities necessarily includes the other roles so I may have to check use the voter? I've also tried using @PreAuthorize("hasRole('ROLE_MANAGER'") on this method but it doesn't seem to be found. Is it required that @PreAuthorize work on only public methods? Thanks!

    Code:
        private void clientTaskDtoToClientTask(ClientTask clientTaskToUpdate, ClientTaskDto clientTaskDto) {
            for (GrantedAuthority authority : SecurityContextHolder.getContext().getAuthentication().getAuthorities()) {
                if (authority.getAuthority().equals(Roles.ROLE_MANAGER)) {
                    log.info(String.format("Found role %s, setting assignment properties on client task.", Roles.ROLE_MANAGER));
                    //Update the clientTask fields
                    clientTaskToUpdate.setAssignedEmployee(clientTaskDto.getClientTask().getAssignedEmployee());
                    clientTaskToUpdate.setDueDate(clientTaskDto.getClientTask().getDueDate());
                }
            }
        }

  2. #2
    Join Date
    Jan 2008
    Posts
    1,834

    Default

    Quote Originally Posted by dukethrash View Post
    So what I want to do is in my method check if the user is ROLE_MANAGER but if the user is ROLE_ADMIN then it should be included (as shown in the hierarchy). It doesn't seem that the granted authorities necessarily includes the other roles so I may have to check use the voter?
    RoleHeiarchy does not add the roles to the users' GrantedAuthority. See the logic inside the RoleHierarchyVoter to see how to use the RoleHiearchy. An example of using it is:

    Code:
    Collection<GrantedAuthority> authorities = roleHierarchy.getReachableGrantedAuthorities(authentication.getAuthorities());
    Quote Originally Posted by dukethrash View Post
    I've also tried using @PreAuthorize("hasRole('ROLE_MANAGER'") on this method but it doesn't seem to be found. Is it required that @PreAuthorize work on only public methods? Thanks!
    You are using proxy based aop, so private methods are not considered. I suggest you read Spring's AOP chapter for details on how it works.
    Rob Winch
    Twitter @rob_winch
    Spring Security Lead
    Spring by Pivotal

  3. #3
    Join Date
    Mar 2010
    Posts
    12

    Default

    That worked! Thank you. I ended up doing the following
    Code:
        
    @Autowired
    private RoleHierarchy roleHierarchy;
    
    // ...
    
    private void clientTaskDtoToClientTask(ClientTask clientTaskToUpdate, ClientTaskDto clientTaskDto) {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            Collection<GrantedAuthority> authorities = roleHierarchy.getReachableGrantedAuthorities(authentication.getAuthorities());
    
            for (GrantedAuthority authority : authorities) {
                if (authority.getAuthority().equals(Roles.ROLE_MANAGER)) {
                    log.info(String.format("Found role %s, setting assignment properties on client task", authority.getAuthority()));
    
                    //Update the clientTask fields
                    clientTaskToUpdate.setAssignedEmployee(clientTaskDto.getClientTask().getAssignedEmployee());
                    clientTaskToUpdate.setDueDate(clientTaskDto.getClientTask().getDueDate());
                }
            }
        }
    It seems like the RoleHierarchy implementation is not so much integrated into GrantedAuthorities and documentation is somewhat weak (even for upcoming Spring Security 3.1). It would be nice to be able to set the RoleHierarchy in the Authentication the same way you can for AccessDecisionManagers.

  4. #4
    Join Date
    Jan 2008
    Posts
    1,834

    Default

    Quote Originally Posted by dukethrash View Post
    It would be nice to be able to set the RoleHierarchy in the Authentication the same way you can for AccessDecisionManagers.
    One reason to keep it out of the Authentication is to keep the values stored in session to a minimum. You can always write your own Authentication implementation that does this.
    Rob Winch
    Twitter @rob_winch
    Spring Security Lead
    Spring by Pivotal

Tags for this Thread

Posting Permissions

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