【问题标题】:Spring Security Role Hierarchy not working with Thymeleaf sec:authorizeSpring Security Role Hierarchy 不适用于 Thymeleaf sec:authorize
【发布时间】:2015-04-20 23:43:29
【问题描述】:

我将 Spring Security 3.2.5.RELEASE 与 ThymeLeaf 2.1.4.RELEASE 一起使用。我已经在我的安全上下文中定义了角色层次结构。在我的视图层中,我使用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>

【问题讨论】:

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


    【解决方案1】:

    为了使角色层次结构在 thymeleaf 模板以及通用安全(注释)配置中起作用,您只需要两件事:

    1. 制作豆子:

      @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);
      }
      

    【讨论】:

      【解决方案2】:

      我遇到了类似层次结构的类似问题。答案在这里解释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>
      

      【讨论】:

      • 非常感谢您的回答。你用的是什么版本的 Spring、Spring Security 和 ThymeLeaf?
      【解决方案3】:

      作为第一个实例,我尝试更新我的依赖项,但没有成功。

      简而言之,我的应用程序具有: - 使用角色层次结构的网络安全配置 - 启用全局方法安全@EnableGlobalMethodSecurity(prePostEnabled = true)

      除 Thymeleaf 表达式外的所有部分都可以正常工作 sec:authorize="hasRole('ROLE_USER')" 没有考虑层次结构。

      然后我尝试调试,发现在计算表达式时,有2个DefaultWebSecurityExpressionHandler: - 1个带钥匙webSecurityExpressionHandler - 1 带有键 defaultWebSecurityExpressionHandler(由我定义的具有层次结构的 bean。

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

      因为我不需要安全表达式处理程序,所以我选择了选项 2。

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

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

      【讨论】:

        猜你喜欢
        • 2021-02-23
        • 2021-03-25
        • 2015-07-05
        • 2020-08-05
        • 2021-01-17
        • 2017-06-09
        • 2021-06-20
        • 2019-10-04
        • 2018-10-31
        相关资源
        最近更新 更多