Spring Security 'Roles' 和 'Privileges' 和 Thymeleaf 'hasRole' 和 'hasAuthority'

Posted

技术标签:

【中文标题】Spring Security \'Roles\' 和 \'Privileges\' 和 Thymeleaf \'hasRole\' 和 \'hasAuthority\'【英文标题】:Spring Security 'Roles' and 'Privileges' and Thymeleaf 'hasRole' and 'hasAuthority'Spring Security 'Roles' 和 'Privileges' 和 Thymeleaf 'hasRole' 和 'hasAuthority' 【发布时间】:2018-10-18 09:55:12 【问题描述】:

使用this 方法,我在前端(Thymeleaf)方面遇到了一些麻烦。一个例子:

用户具有角色admin(该角色分配有两个权限readwrite) 用户具有角色user(该角色仅分配有read 权限)

在前端,我将保护不同的divs。如果我使用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 的容器,有没有办法允许访问div 以获得“整个”role?我真的必须列出所有privileges吗?还是我在这里混合了一些东西?谢谢。

主要思想是:

用户1

with Role 'admin'

        with Privilege 'read' / 'write'

用户2

with Role 'user'

        with Privilege 'read'

在百里香中:

为所有具有管理员角色的用户显示一个 div

&lt;li sec:authorize="hasRole('ROLE_ADMIN')"&gt;Entry 1&lt;/li&gt;

并显示所有具有写入权限的 div

&lt;li sec:authorize="hasAuthority('READ_PRIVILEGE')"&gt;Entry 1&lt;/li&gt;

这甚至可能/“要走的路吗?”我的意思是,如果我不能为整个组授予对页面的访问权限,那么将权限分组到一个组(角色)是什么意思?

【问题讨论】:

可能是 Spring Security 自动为角色添加了 ROLE_ 前缀。如果您尝试hasRole('ROLE_ADMIN'),会发生什么? hasRole('ROLE_ADMIN') 有效..我不知道在数据库中角色的名称也必须是 ROLE_ADMIN (因为前缀是自动添加的,我认为它可以处理ADMIN).. Spring 4 对此进行了一些更改。见docs.spring.io/spring-security/site/migrate/current/3-to-4/… 【参考方案1】:

通常,您不需要包含 ROLE_ 前缀。

但是,当涉及到 Thymeleaf 时,不仅要包含它,它还区分大小写:

<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]

Reference

【讨论】:

我得到了hasRoleworking..但是,这并不能真正回答问题..使用问题中的方法,我必须列出角色的所有权限才能显示它,我不能简单地授予访问“整体”角色?更新问题... @manu 我不清楚你想说什么,你想完全阻止一个小组看到一个页面? 我想知道当我按照问题中链接的方法时是否无法授予对角色和权限的访问权限。如果我必须在 Thymeleaf 中以任何方式列出所有权限,那么让一个组“管理员”具有权限的原因是什么? @manu 您不必列出所有权限。默认情况下,除非您另外指定,否则每个人都可以访问页面中的所有内容。 我知道,但假设我想授予对每个权限的访问权限,但有时我确实需要列出权限吗?【参考方案2】:

鉴于您的 cmets,我认为这可能与您的角色缺少 ROLE_ 前缀和/或 Spring Security 4 中的行为变化有关。

角色在填充时通常会自动添加前缀。例如DefaultLdapAuthoritiesPopulator 包含一个rolePrefix 属性,默认设置为ROLE_(参见the source 和these docs)。因此,通过 LDAP 检索到的所有角色都将自动添加前缀。如果你的情况是这种情况,当然取决于你如何填充你的角色。

自 Spring Security 4 起,DefaultWebSecurityExpressionHandler 默认为hasRole(String)hasAnyRole(String...) 添加一个ROLE_ 前缀(参见the source)。例如,如果使用了hasRole("ADMIN"),那么ROLE_ADMIN 角色将被DefaultWebSecurityExpressionHandler 检查。

使用hasAuthority("ADMIN") 确实有效,因为没有为该表达式添加前缀。

因此,在您的情况下,如果您的角色填充没有ROLE_,则使用hasRole("ADMIN") 实际上可能会尝试匹配ROLE_ADMIN,具体取决于您使用的Spring Security 版本。这也会影响 Thymeleaf,因为 Thymeleaf 只是使用 Spring Security 功能。

【讨论】:

以上是关于Spring Security 'Roles' 和 'Privileges' 和 Thymeleaf 'hasRole' 和 'hasAuthority'的主要内容,如果未能解决你的问题,请参考以下文章

在 Spring Security 中保护两个或多个 /** url

spring boot 整合spring security中spring security版本升级的遇到的坑

spring bootspring security

Swagger + Spring security - 基于角色隐藏方法

Spring boot @ElementCollection:“字段列表”中的未知列“user_roles”

基于 ROLES 的 Spring 安全授权不起作用