Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AccessDeniedException if using RoleHierarchyImpl

I am using role hierarchy in Spring Security.

<beans:bean id="roleVoter" class="org.springframework.security.access.vote.RoleHierarchyVoter">
    <beans:constructor-arg ref="roleHierarchy" />
</beans:bean>

<beans:bean id="roleHierarchy"
        class="org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl">
    <beans:property name="hierarchy">
        <beans:value>
            ROLE_USER > ROLE_GUEST
        </beans:value>
    </beans:property>
</beans:bean>

I am securing methods using protect-pointcut

<global-method-security secured-annotations="enabled" pre-post-annotations="enabled">
  <protect-pointcut expression="execution(* my.package.*(..))"
     access="ROLE_GUEST"/>
</global-method-security>

However, I got AccessDeniedException if I login with user that has authority ROLE_USER. I have no issue if I specified protect-pointcut with access="ROLE_GUEST,ROLE_USER".

Am I missing some steps? FYI, I am using Spring 3.0.5.

Thanks.

like image 497
Lee Chee Kiam Avatar asked Dec 03 '25 19:12

Lee Chee Kiam


2 Answers

Don't forget to add a WebExpressionVoter to be able to also use expressions in http element:

<sec:http use-expressions="true" access-decision-manager-ref="accessDecisionManager">
   <sec:intercept-url pattern="/index.html" access="hasRole('ROLE_AUTHENTICATED')" />
   <sec:intercept-url pattern="/admin" access="hasRole('ROLE_SUPERVISOR')" />
   ...

So I end up with an accessDecisionManager containing a role hierarchy voter and a WebExpressionVoter, both using the same roleHierarchyImpl bean.

<bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
  <property name="decisionVoters">
    <list>
       <ref bean="roleHierarchyVoter" />
       <bean class="org.springframework.security.web.access.expression.WebExpressionVoter">
           <property name="expressionHandler">
            <bean class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler">
               <property name="roleHierarchy" ref="roleHierarchy"/>
            </bean>
        </property>
       </bean>
       <bean class="org.springframework.security.access.vote.AuthenticatedVoter"/>
    </list>
  </property>
</bean>
<bean id="roleHierarchyVoter" class="org.springframework.security.access.vote.RoleHierarchyVoter">
    <constructor-arg ref="roleHierarchy" />
</bean>

<bean id="roleHierarchy" class="org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl">
    <property name="hierarchy">
        <value>
            ROLE_SUPERVISOR > ROLE_XX
            ROLE_XX > ROLE_AUTHENTICATED
            ROLE_AUTHENTICATED > ROLE_UNAUTHENTICATED
        </value>
    </property>
</bean>

(spring sec 3.1)

like image 128
jgraglia Avatar answered Dec 06 '25 16:12

jgraglia


The nested beans are slightly wrong in jgraglia example above, and you don't need <ref bean="roleHierarchyVoter" /> because the hierarchy is handled in WebExpressionVoter. I'm doing this in Spring Security 4.0.0, but the code looks the same except you don't need use-expressions="true" because it's on by default.

I usually try and nest my beans as much as possible, so my code has no ref="" values unless required.

<bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
   <constructor-arg>
        <bean class="org.springframework.security.web.access.expression.WebExpressionVoter">
            <property name="expressionHandler" ref="webExpressionHandler" />
        </bean>
   </constructor-arg>
</bean>

<bean id="webExpressionHandler" class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler">
    <property name="roleHierarchy" ref="roleHierarchy"/>
</bean>

<bean id="roleHierarchy" class="org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl">
    <property name="hierarchy">
        <value>
            ROLE_ADMIN > ROLE_USER
            ROLE_USER > ROLE_ANONYMOUS
        </value>
    </property>
</bean>
like image 20
Jim Richards Avatar answered Dec 06 '25 16:12

Jim Richards