使用这种方法,我在前端(Thymeleaf(上遇到了一些麻烦。举个例子:
- 用户具有角色
admin
(为角色分配了两个权限read
和write
( - 用户具有角色
user
(仅为角色分配read
权限(
在前端,我将保护不同的div
。如果我使用admin
登录:
<li sec:authorize="hasRole('admin')">Entry 1</li>
<li sec:authorize="hasAnyRole('admin', 'user')">Entry 2</li>
什么也没显示,而
<li sec:authorize="hasAuthority('read')">Entry 3</li>
<li sec:authorize="hasAnyAuthority('read', 'write')">Entry 4</li>
完美工作。
现在,由于我将role
用作privileges
的容器,是否无法允许访问"整个"role
的div
?我真的必须列出所有privileges
吗?还是我在这里混杂了一些东西?谢谢。
主要思想是:
用户1
with Role 'admin' with Privilege 'read' / 'write'
用户2
with Role 'user' with Privilege 'read'
在百里香叶中:
为具有角色管理员的所有用户显示div
<li sec:authorize="hasRole('ROLE_ADMIN')">Entry 1</li>
并显示具有特权写入的所有用途的div
<li sec:authorize="hasAuthority('READ_PRIVILEGE')">Entry 1</li>
这甚至可能/"要走的路"吗?我的意思是,如果我无法为整个组授予对页面的访问权限,将权限分组到组(角色(有什么意义?
通常,您不需要包含ROLE_
前缀。
但是,当涉及到百里香叶时,您不仅必须包含它,而且还区分大小写:
<li sec:authorize="hasRole('ROLE_ADMIN')">Admin</li>
<li sec:authorize="hasRole('ROLE_USER')">User</li>
此外,ROLE_USER
的替代方法(默认情况下,所有经过身份验证的用户都被赋予该角色(是改用isAuthenticated()
,如下所示:
<li sec:authorize="isAuthenticated()">Authenticated users can see this</li>
如果您想查看当前用户拥有哪些类型的角色,可以在页面中添加以下内容:
<span sec:authentication="principal.authorities"></span>
它应该在加载页面时呈现一系列角色,例如[ROLE_USER, ROLE_ADMIN]
参考
鉴于您的评论,我认为这可能与您的角色缺少ROLE_
前缀和/或 Spring Security 4 中的行为变化有关。
填充角色时通常会自动添加前缀。例如,DefaultLdapAuthoritiesPopulator
包含一个默认设置为ROLE_
的rolePrefix
属性(请参阅源和这些文档(。因此,通过 LDAP 检索的所有角色将自动添加前缀。如果是这种情况,当然取决于您如何填充角色。
从 Spring Security 4 开始,默认情况下DefaultWebSecurityExpressionHandler
会向hasRole(String)
和hasAnyRole(String...)
添加ROLE_
前缀(请参阅源代码(。例如,如果使用hasRole("ADMIN")
,则角色ROLE_ADMIN
将由DefaultWebSecurityExpressionHandler
检查。
使用hasAuthority("ADMIN")
确实有效,因为不会为该表达式添加前缀。
因此,在您的情况下,如果您的角色填充没有ROLE_
,则使用hasRole("ADMIN")
实际上可能会尝试与ROLE_ADMIN
匹配,具体取决于您使用的 Spring 安全版本。这也会影响 Thymeleaf,因为 Thymeleaf 只是使用 Spring Security 功能。