我在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>
我正在使用protect-pointcut确保方法
<global-method-security secured-annotations="enabled" pre-post-annotations="enabled">
<protect-pointcut expression="execution(* my.package.*(..))"
access="ROLE_GUEST"/>
</global-method-security>
但是,如果我使用具有权限ROLE_USER的用户登录,则会出现AccessDeniedException。如果我使用access="ROLE_GUEST,ROLE_USER"
指定保护切入点,我没有问题。
我错过了一些步骤吗?仅供参考,我使用的是Spring 3.0.5。
感谢。
答案 0 :(得分:8)
不要忘记添加WebExpressionVoter以便能够在http元素中使用表达式:
<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')" />
...
所以我最终得到一个包含角色层次结构投票者和WebExpressionVoter的accessDecisionManager,两者都使用相同的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>
(春季第3.1节)
答案 1 :(得分:3)
嵌套bean在上面的jgraglia示例中略有错误,并且您不需要<ref bean="roleHierarchyVoter" />
,因为层次结构是在WebExpressionVoter
中处理的。我在Spring Security 4.0.0中执行此操作,但代码看起来相同,除非您不需要use-expressions="true"
,因为默认情况下它已启用。
我通常会尝试尽可能地嵌套我的bean,因此除非需要,否则我的代码没有ref=""
值。
<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>
答案 2 :(得分:2)
查看错误报告SEC-1163以及下面的评论。
如果您需要对角色层次结构的基本支持,请使用RoleHierarchyVoter而不是RoleVoter。
所以你需要一些想法:
<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>