@RolesAllowed与@PreAuthorize与@Secured的区别

35

我有一个基本的SpringBoot应用程序,使用Spring Initializer、嵌入式Tomcat、Thymeleaf模板引擎,并将其打包为可执行的JAR文件。

我想要保护一个控制器:

@Controller
@RequestMapping("/company")
@RolesAllowed({"ROLE_ADMIN"})
@PreAuthorize("hasRole('ADMIN')")
@Secured("ADMIN")
public class CompanyController {
}

我知道有不同的选择,但我不确定应该使用哪一个。


问题应该被编辑为 @RolesAllowed("ADMIN")@Secured("ROLE_ADMIN")。(参见此链接。) - Leponzo
3个回答

49

安全注解

@PreAuthorize@RolesAllowed@Secured都是注解,允许配置方法安全。它们既可以应用于单个方法,也可以应用于类级别,在后一种情况下,安全约束将应用于类中的所有方法。

使用Spring AOP代理实现了方法级安全。

@PreAuthorize

@PreAuthorize注解允许使用Spring表达式语言(SpEL)来指定对方法的访问限制。这些限制在方法执行之前进行评估,如果不满足约束条件,则可能导致拒绝执行该方法。 @PreAuthorize注解是Spring Security框架的一部分。

为了能够使用@PreAuthorize,需要将@EnableGlobalMethodSecurity注解中的prePostEnabled属性设置为true

@EnableGlobalMethodSecurity(prePostEnabled=true)

@RolesAllowed

@RolesAllowed注释源于Java安全标准JSR-250。与@PreAuthorize注释相比,此注释的功能更为有限,因为它仅支持基于角色的安全性。

要使用@RolesAllowed注释,需要将包含该注释的库放在类路径中,因为它不是Spring Security的一部分。此外,@EnableGlobalMethodSecurity注释的jsr250Enabled属性需要设置为true

@EnableGlobalMethodSecurity(jsr250Enabled=true)

@Secured

@Secured 注释是一个可以用于配置方法安全性的旧版 Spring Security 2 注释。它支持多种安全性而不仅仅是基于角色的安全性,但不支持使用Spring表达式语言(SpEL)指定安全性约束。建议在新应用程序中使用@PreAuthorize注释而不是此注释。

需要在@EnableGlobalMethodSecurity注释中显式启用对@Secured注释的支持,使用securedEnabled属性:

@EnableGlobalMethodSecurity(securedEnabled=true)

哪些安全注释允许使用SpEL

下表展示了Spring Security 5中可用于安全注释的Spring表达式语言支持:

╔═════════════════════╦═══════════════════╗
║ Security Annotation ║ Has SpEL Support? ║
╠═════════════════════╬═══════════════════╣
║  @PreAuthorize      ║        yes        ║
╠═════════════════════╬═══════════════════╣
║  @PostAuthorize     ║        yes        ║
╠═════════════════════╬═══════════════════╣
║  @PreFilter         ║        yes        ║
╠═════════════════════╬═══════════════════╣
║  @PostFilter        ║        yes        ║
╠═════════════════════╬═══════════════════╣
║  @Secured           ║        no         ║
╠═════════════════════╬═══════════════════╣
║  @RolesAllowed      ║        no         ║
╚═════════════════════╩═══════════════════╝

1
这里只是一个小提示,@EnableGlobalMethodSecurity现在已经被弃用,推荐使用@EnableMethodSecurity,它现在默认为prePostEnabled=true,只需要指定另外两个参数:securedEnabled=true或者jsr250Enabled=true(如果需要的话)。 - undefined

20

@Secured@RolesAllowed 在 Spring 中执行相同的功能。不同之处在于,@Secured 是一个特定于 Spring 的注释,而 @RolesAllowed 是一个 Java 标准注释(JSR250)。这两个注释都不支持 SpEL。

@PreAuthorize 是另一个特定于 Spring 的注释。你可以使用 SpEL 执行更多功能强大的操作,可以编写表达式来限制方法调用,基于角色/权限、当前经过身份验证的用户和传递到方法中的参数。

@PreAuthorize("hasRole('ADMIN') or #user.id == authentication.name")
public void deleteUser(User user) {
    ...
}

关于使用哪个,完全取决于您。 @Secure@PreAuthorize 会将您的代码与Spring绑定。如果被绑定到Spring不是问题或者您需要执行更强大的操作,请使用@PreAuthorize

http://docs.spring.io/autorepo/docs/spring-security/4.0.x/reference/html/el-access.html#el-common-built-in


5
所有这些对你来说基本上都是一样的,但对于控制器和控制器方法来说,@PreAuthorize 最合适。@Secured@RolesAllowed 用于描述服务层安全属性。
此外,请注意使用 @PreAuthorize 注释需要定义一个配置类:
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
...
}

为什么@PreAuthorize是控制器的最佳选择? - birca123

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接