Spring安全角色层次结构不适用于Thymeleaf sec:授权

时间:2015-02-19 15:02:54

标签: java spring spring-mvc spring-security thymeleaf

我正在使用Spring Security 3.2.5.RELEASE和ThymeLeaf 2.1.4.RELEASE。我在安全上下文中定义了Role Hierarchy。在我的视图层中,我使用sec:authorize属性来定义菜单项。我希望看到顶级角色下的所有菜单项,但我只看到该角色下定义的菜单。如何解决这个问题,以便在顶层看到所有菜单?

任何指针都会非常感激。感谢。

<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_ADMINISTRATOR > ROLE_MANAGER > ROLE_CONTENT_ADMINISTRATOR
        </beans:value>
    </beans:property>
</beans:bean>

在我的视图页面中,我正在使用sec:authorize属性,如下所示:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<body th:fragment="admin-menu" sec:authorize="hasRole('ROLE_ADMINISTRATOR')">
<li>
    <a href="#"><i class="fa fa-users"></i> <span class="nav-label">Users</span> </a>
</li>
</body>
</html>

3 个答案:

答案 0 :(得分:4)

为了使角色层次结构在百万富翁模板以及通用安全(注释)配置中运行,您只需要两件事:

  1. 制作bean:

    @Bean
    public RoleHierarchyImpl roleHierarchy() {
    RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
    String hierarchy =
            "ADMIN_GLOBAL_MANAGEMENT > ADMIN_COMMON " +
            "ADMIN_GLOBAL_MANAGEMENT > ADMIN_USER_MANAGEMENT " +
            "ADMIN_GLOBAL_MANAGEMENT > ADMIN_PAYMENT_MANAGEMENT " +
            "ADMIN_GLOBAL_MANAGEMENT > ADMIN_MESSAGE_MANAGEMENT";
     roleHierarchy.setHierarchy(hierarchy);
     return roleHierarchy;
    }
    
  2. 扩展 WebSecurityConfigurerAdapter 并覆盖方法:

    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
    ...
    
    @Override
    public void configure(WebSecurity web) throws Exception {
      DefaultWebSecurityExpressionHandler expressionHandler = new 
        DefaultWebSecurityExpressionHandler();
      expressionHandler.setRoleHierarchy(roleHierarchy());
      web.expressionHandler(expressionHandler);
    }
    

答案 1 :(得分:0)

我遇到了类似层次结构的类似问题。答案在这里解释Spring Security Role Hierarchy issues。这对我有用:

<sec:http> ...
    <sec:expression-handler ref="defaultWebSecurityExpressionHandler" />
...

<beans:bean id="roleHierarchy" class="org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl">
    <beans:property name="hierarchy">
        <beans:value>
            ROLE_SYSTEMADMIN > ROLE_JOURNALADMIN
            ROLE_JOURNALADMIN > ROLE_ESUBS
            ROLE_ESUBS > ROLE_STAFF
        </beans:value>
    </beans:property>
</beans:bean>

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

<beans:bean id="defaultWebSecurityExpressionHandler"
      class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler">
      <beans:property name="roleHierarchy" ref="roleHierarchy"/>
</beans:bean>


 <beans:bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
    <beans:constructor-arg>
        <beans:list>
            <beans:bean id="roleVoter" class="org.springframework.security.access.vote.RoleHierarchyVoter">
                <beans:constructor-arg ref="roleHierarchy" />
            </beans:bean>
            <beans:bean class="org.springframework.security.web.access.expression.WebExpressionVoter">
                <beans:property name="expressionHandler" ref="defaultWebSecurityExpressionHandler"/>
            </beans:bean>
        </beans:list>
    </beans:constructor-arg>
</beans:bean>

答案 2 :(得分:0)

作为第一个例子,我试图更新我的依赖项,但没有运气。

我的申请很快就有了: - 使用角色层次结构的Web安全配置 - 启用全局方法安全性@EnableGlobalMethodSecurity(prePostEnabled = true)

除Thymeleaf表达外,所有部分均正常工作 sec:authorize="hasRole('ROLE_USER')"未考虑等级制度。

然后我尝试调试,我发现在评估表达式时,有2 DefaultWebSecurityExpressionHandler: - 1个密钥webSecurityExpressionHandler - 1,键defaultWebSecurityExpressionHandler(我用层次结构定义了bean。

所以我有两个选择: - 拦截webSecurityExpressionHandler和d设置角色层次结构;要么 - 将我的bean定义从defaultWebSecurityExpressionHandler重命名为webSecurityExpressionHandler

由于我不需要安全表达式处理程序,所以我选择了第2个选项。

注意: 如果您想查看是否没有其他bean,请参阅 org.thymeleaf.extras.springsecurity4.auth.AuthUtils@243(第243行,方法getExpressinHandler)

旧版本可能就是这种情况(包括Thymeleaf 2.x.x)