AccessDeniedException if using RoleHierarchyImpl

我怕爱的太早我们不能终老 提交于 2019-12-29 07:15:14

问题


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.


回答1:


Have a look at bug report SEC-1163 and the comment below.

If you want basic support for role hierarchies, then use a RoleHierarchyVoter, instead of a RoleVoter.

So you need somethink 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:


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)




回答3:


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>


来源:https://stackoverflow.com/questions/7809313/accessdeniedexception-if-using-rolehierarchyimpl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!