无法使用@PreAuthorize来处理角色层次结构

时间:2013-07-09 01:35:06

标签: java spring-security

我有一个自定义身份验证提供程序,它返回'AbstractAuthenticationToken with ROLE_ADMIN only. I have a method annotated with @ PreAuthorize(“hasRole('ROLE_USER')”)的具体实现。我正在尝试设置角色层次结构,以便我的管理员用户可以访问此方法。

我在spring-security.xml中有以下内容:

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

<beans:bean id="methodExpressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
    <beans:property name="roleHierarchy" ref="roleHierarchy" />
</beans:bean>

<sec:global-method-security pre-post-annotations="enabled">
    <sec:expression-handler ref="methodExpressionHandler" />
</sec:global-method-security>

对受保护方法的请求被拒绝,但是如果我将注释更改为@PreAuthorize("hasRole('ROLE_ADMIN')")则可以。

我在AccessDeniedException上放了一个断点,这是从AffirmativeBased.decide(...)抛出的。问题似乎是PreInvocationAuthorizationAdviceVoter的{​​{1}}是expressionHandler。这告诉我,在我的roleHierarchy或methodExpressionHandler的连接中出现了问题。

我的spring-security.xml有什么明显错误吗?有什么我误解了这些东西应该如何运作?

2 个答案:

答案 0 :(得分:1)

哦,我多么愚蠢......我的问题没有足够的背景来回答这个问题,但我已经解决了。

我的<global-method-security>和我的spring-security.xml都有dispatcher-servlet.xml。我只是在spring-security中做出改变。

当我在DefaultMethodSecurityExpressionHandler的构造函数上放置一个断点时,赠送。它被叫了两次。一个是setRoleHierarchy被叫,另一个不是。

解决方案是:

  1. 将公共角色层次结构定义移出到单独的文件,以便spring-security.xmldispatcher-servlet.xml导入。
  2. <global-method-security>methodExpressionHandler bean从spring-security.xml移至dispatcher-servlet.xml

答案 1 :(得分:0)

尝试将roleHierarhy注入roleVoterofficial documentation的示例:

<bean id="roleVoter" 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_ADMIN > ROLE_STAFF
            ROLE_STAFF > ROLE_USER
            ROLE_USER > ROLE_GUEST
        </value>
    </property>
</bean>