48

我想使用 Spring Security JSP 标签库根据角色有条件地显示一些内容。但是在 Spring Security 3.1.x 中只检查一个角色。

我可以使用,但不推荐使用ifAllGranted

有什么帮助吗?

4

5 回答 5

89

spring security中有一个特殊的安全表达式:

hasAnyRole(list of roles) - 如果用户已被授予任何指定的角色(以逗号分隔的字符串列表形式给出),则为 true。

我从未使用过它,但我认为这正是您正在寻找的。

示例用法:

<security:authorize access="hasAnyRole('ADMIN', 'DEVELOPER')">
    ...
</security:authorize>

这是描述标准弹簧安全表达式的参考文档的链接。此外,这里是一个讨论,我在其中描述了如何在需要时创建自定义表达式。

于 2012-07-13T11:11:25.653 回答
8

@dimas 的回答在逻辑上与您的问题不一致;ifAllGranted不能直接替换hasAnyRole

来自Spring Security 3—>4 迁移指南

老的:

<sec:authorize ifAllGranted="ROLE_ADMIN,ROLE_USER">
    <p>Must have ROLE_ADMIN and ROLE_USER</p>
</sec:authorize>

新(SPeL):

<sec:authorize access="hasRole('ROLE_ADMIN') and hasRole('ROLE_USER')">
    <p>Must have ROLE_ADMIN and ROLE_USER</p>
</sec:authorize>

ifAllGranted直接替换为hasAnyRole将导致 spring 使用 anOR而不是AND. 也就是说,如果经过身份验证的主体包含至少一个hasAnyRole指定角色,则将返回,而 Spring(现在从 Spring Security 4 开始不推荐使用)方法仅在经过身份验证的主体包含所有指定角色时才返回。trueifAllGrantedtrue

TL;DR:要复制ifAllGranted使用 Spring Security Taglib 的新身份验证表达式语言的行为,hasRole('ROLE_1') and hasRole('ROLE_2')需要使用该模式。

于 2016-11-18T00:50:12.867 回答
2

如果您使用的是百里香,您可以尝试这种方式

sec:authorize="hasAnyRole(T(com.orsbv.hcs.model.SystemRole).ADMIN.getName(),
               T(com.orsbv.hcs.model.SystemRole).SUPER_USER.getName(),'ROLE_MANAGEMENT')"

如果用户具有提到的角色,这将返回 true,否则返回 false。

请注意,您必须像这样在 html 声明标签中使用 sec 标签

<html xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
于 2019-09-18T07:59:49.843 回答
1

我用过hasAnyRole('ROLE_ADMIN','ROLE_USER'),但我在错误下创建了 bean

Error creating bean with name     'org.springframework.security.web.access.intercept.FilterSecurityInterceptor#0': Cannot create inner bean '(inner bean)' of type [org.springframework.security.web.access.expression.ExpressionBasedFilterInvocationSecurityMetadataSource] while setting bean property 'securityMetadataSource'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#2': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.security.web.access.expression.ExpressionBasedFilterInvocationSecurityMetadataSource]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: Expected a single expression attribute for [/user/*]

然后我尝试了

access="hasRole('ROLE_ADMIN') or hasRole('ROLE_USER')"它对我来说很好。

因为我的用户之一是管理员和用户。

为此,您需要添加use-expressions="true" auto-config="true"后跟 http 标记

<http use-expressions="true" auto-config="true" >.....</http>
于 2015-08-13T13:33:51.327 回答
1

在 Spring Boot 2.4 中,它是

sec:authorize="hasAnyRole('ROLE_ADMIN')

确保您有

thymeleaf-extras-springsecurity5

在您的依赖项中。还要确保包含命名空间

xmlns:sec="http://www.thymeleaf.org/extras/spring-security"

在你的 html...

于 2020-11-28T16:10:58.857 回答