【问题标题】:Can't get @PreAuthorize to work with role hierarchies无法让 @PreAuthorize 使用角色层次结构
【发布时间】:2013-07-06 11:48:44
【问题描述】:

我有一个自定义身份验证提供程序,它返回 'AbstractAuthenticationTokenwithROLE_ADMINonly. 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(...) 抛出的。问题似乎是PreInvocationAuthorizationAdviceVoterexpressionHandlernull。这表明我的 roleHierarchy 或 methodExpressionHandler 的连接有问题。

我的 spring-security.xml 有什么明显的问题吗?我对这些东西应该如何工作有什么误解吗?

【问题讨论】:

    标签: java spring-security


    【解决方案1】:

    尝试将roleHierarhy 注入roleVoter。来自official 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>
    

    【讨论】:

    • 不走运。 PreInvocationAuthorizationAdviceVoter 的 expressionHandler 仍然为 null,而 accessDecisionManager 中的第二个投票者只是一个普通的 RoleVoter。我将尝试显式定义 accessDecisionManager,但我确信我以前一直在走这条路。
    【解决方案2】:

    哦,我真傻……我的问题没有足够的上下文来回答这个问题,但我已经解决了。

    我的spring-security.xmldispatcher-servlet.xml 都有&lt;global-method-security&gt;。我只是在 spring-security 中进行更改。

    当我在DefaultMethodSecurityExpressionHandler 的构造函数上设置了一个断点时,我就放弃了。它被调用了两次。一个叫setRoleHierarchy,另一个没有。

    解决办法是:

    1. 将通用角色层次结构定义移到单独的文件中,以便spring-security.xmldispatcher-servlet.xml 导入。
    2. &lt;global-method-security&gt;methodExpressionHandler bean 从spring-security.xml 移动到dispatcher-servlet.xml

    【讨论】:

    • 我也有同样的问题。我尝试了您的解决方案,但无法正常工作。在 spring-security.xml 和 dispatcher-servlet.xml 中包含 RoleHierarchy bean 的另一件事。我们不能在一个文件中拥有整个配置吗?
    猜你喜欢
    • 2020-10-09
    • 2010-11-19
    • 2020-03-17
    • 2013-11-18
    • 2012-06-16
    • 2017-12-27
    • 1970-01-01
    • 2011-11-03
    • 2016-01-03
    相关资源
    最近更新 更多