Spring Security: 在 Java 中检查用户是否具有角色
最后更新:2025 年 3 月 26 日
1. 简介
在 Spring Security 中,有时需要检查经过身份验证的用户是否具有特定角色。这对于启用或禁用应用程序中的特定功能非常有用。
在本教程中,我们将了解在 Java 中使用 Spring Security 检查用户角色的各种方法。
2. 在 Java 中检查用户角色
Spring Security 提供了几种在 Java 代码中检查用户角色的方法。我们将在下面查看每种方法。
2.1. @PreAuthorize
在 Java 中检查用户角色的第一种方法是使用 Spring Security 提供的 @PreAuthorize 注解。 此注释可以应用于类或方法,并接受一个字符串值,该值表示 SpEL 表达式。
在使用此注释之前,我们必须首先启用全局方法安全。 这可以通过在任何配置类中添加 @EnableGlobalMethodSecurity 注解来完成。
然后,Spring Security 提供了两种可以使用 @PreAuthorize 注解来检查用户角色的表达式
@PreAuthorize("hasRole('ROLE_ADMIN')")
@GetMapping("/user/{id}")
public String getUser(@PathVariable("id") String id) {
...
}
我们还可以在单个表达式中检查多个角色
@PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_MANAGER')")
@GetMapping("/users")
public String getUsers() {
...
}
在这种情况下,如果用户具有任何指定的角色,则允许该请求。
如果未赋予适当的角色就调用该方法,Spring Security 会抛出异常并重定向到 错误页面。
2.2. SecurityContext
我们在 Java 代码中检查用户角色的另一种方法是使用 SecurityContext 类。
默认情况下,Spring Security 使用该类的线程本地副本。 这意味着我们应用程序中的每个请求都具有其安全上下文,其中包含发出请求的用户的详细信息。
要使用它,我们只需调用 SecurityContextHolder 中的静态方法
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null && auth.getAuthorities().stream().anyMatch(a -> a.getAuthority().equals("ADMIN"))) {
...
}
请注意,我们在这里使用纯粹的权限名称,而不是完整的角色名称。
当我们需要更细粒度的检查(例如,单个方法的特定部分)时,这可以很好地工作。 但是,如果我们在 Spring Security 中使用全局上下文持有者模式,此方法将不起作用。
2.3. UserDetailsService
我们可以查找用户角色的第三种方法是使用 UserDetailsService。 这是一个我们可以在应用程序中的任何地方注入的 bean,并根据需要调用它
@GetMapping("/users")
public String getUsers() {
UserDetails details = userDetailsService.loadUserByUsername("mike");
if (details != null && details.getAuthorities().stream()
.anyMatch(a -> a.getAuthority().equals("ADMIN"))) {
// ...
}
}
同样,我们必须使用权限名称,而不是带有前缀的完整角色名称。
此方法的优点是我们能够检查任何用户的角色,而不仅仅是发出请求的用户。
2.4. Servlet 请求
如果我们使用 Spring MVC,我们还可以使用 HttpServletRequest 类在 Java 中检查用户角色
@GetMapping("/users")
public String getUsers(HttpServletRequest request) {
if (request.isUserInRole("ROLE_ADMIN")) {
...
}
}
3. 结论
在本文中,我们已经了解了使用 Java 代码和 Spring Security 检查角色的一些不同方法。
支持本文的代码可在 GitHub 上获取。 一旦你以 Baeldung Pro 会员 身份登录,就开始学习并在项目上进行编码。















