AccessDeniedException when using RoleHierarchyImpl

I use the 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 protect methods using point-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 an AccessDeniedException if I log in with a user with ROLE_USER authority. I have no problem if I specified a point-pointcut with access="ROLE_GUEST,ROLE_USER" .

Did I skip a few steps? FYI, I am using Spring 3.0.5.

Thanks.

+3
spring spring-security
source share
3 answers

See SEC-1163 bug report and comment below.

If you need basic support for role hierarchies, use RoleHierarchyVoter instead of RoleVoter.

So you need something like:

 <bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased"> <property name="decisionVoters"> <list> <ref bean="roleHierarchyVoter" /> <ref bean="authenticatedVoter" /> <ref bean="preAdviceVoter" /> <ref bean="mediaItemReadVoter" /> <ref bean="mediaItemWriteVoter" /> </list> </property> </bean> <bean id="roleVoter" class="org.springframework.security.access.vote.RoleHierarchyVoter"> <constructor-arg ref="roleHierarchy"/> </bean> 
+2
source share

Remember to add WebExpressionVoter to be able to use expressions in the 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 have an accessDecisionManager containing a role hierarchy selector and 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 p. 3.1)

+8
source share

The nested beans are slightly incorrect in the jgraglia example above, and you do not need <ref bean="roleHierarchyVoter" /> because the hierarchy is processed in WebExpressionVoter . I do this in Spring Security 4.0.0, but the code looks the same, except that you do not need use-expressions="true" because it is the default.

I usually try to enclose my beans as much as possible, so my code does not have ref="" values ​​if it is not 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> 
+3
source share

All Articles