Spring Security Role Hierarchy 不适用于 Thymeleaf sec:authorize
Posted
技术标签:
【中文标题】Spring Security Role Hierarchy 不适用于 Thymeleaf sec:authorize【英文标题】:Spring Security Role Hierarchy not working with 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>
【问题讨论】:
【参考方案1】:为了使角色层次结构在 thymeleaf 模板以及通用安全(注释)配置中起作用,您只需要两件事:
制作豆子:
@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;
扩展 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)中的情况
【讨论】:
以上是关于Spring Security Role Hierarchy 不适用于 Thymeleaf sec:authorize的主要内容,如果未能解决你的问题,请参考以下文章
Spring Security 中 Role 和 GrantedAuthority 的区别
不再需要 Spring Security ROLE_ 前缀?
Grails spring security LDAP 从 LDAP 基础获取 ROLE
带有 ROLE_ANONYMOUS 的 AngularJS 和 Spring Security 仍然返回 401