Spring Security权限控制系列(六)

环境:Springboot2.4.12 + Spring Security 5.4.9
本篇主要内容:业务接口权限认证上一篇:《Spring Security权限控制系列(五)》
演示案例
有如下接口:
@RestController
@RequestMapping("/business")
public class BussinessController {
@GetMapping("/{id}")
public Object get(@PathVariable("id") Integer id) {
return "receive - " + id ;
}
}安全配置:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable() ;
http.authorizeRequests().antMatchers("/resources/**",权限 "/cache/**", "/process/login").permitAll() ;
http.authorizeRequests().antMatchers("/demos/**").hasRole("USERS") ;
http.authorizeRequests().antMatchers("/api/**").hasRole("ADMIN") ;
// 上面的配置都是基于之前的文章,这里我们不需要关心,控制仅仅看下面这个接口配置接口
// 这里我们会要求所有以/business开始的系列所有请求
http.authorizeRequests().antMatchers("/business/**").authenticated() ;
}
}有了上面的配置,启动服务访问http://localhost:8080/business/100接口时会要求登录,权限只要登录成功,控制接口就可以访问。系列
这里我不希望通过如下方式进行的权限权限设置:
// hasRole("xxx") 或 hasAuthority("xxxx")
http.authorizeRequests().antMatchers("/business/**").hasRole("xxx")这种写法限定了所有的/business开头的请求都由于固定的权限,/business可能会有很多的控制子接口,每种子接口可能我们都需要定义不同的系列权限才可访问,这时候如果在通过上面的权限方式配置就太繁琐了。Spring Security还提供了基于访问注解的控制方式细化接口权限的控制定义,接下来使用基于注解的系列方式控制Controller接口权限。高防服务器
注意:并不是权限基于注解的权限控制只能应用到Controller上,只是控制我们一般都会加到Controller上;其实任何Service方法都是可以使用的。这些注解也可以直接加到接口方法上。系列
开启方法认证
@Configuration
@EnableGlobalMethodSecurity(jsr250Enabled = true, prePostEnabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
}属性说明:
jsr250Enabled:启用对JSR-250注释的支持。@RolesAllowed。
prePostEnabled:启用基于表达式的语法支持(jsr250Enabled和securedEnabled都是基于简单角色的约束)。@PreAuthorize。
securedEnabled:启用@Secured注解的支持。
示例:
@GetMapping("/{id}")
@RolesAllowed("ROLE_USERS") // ①
@Secured("ROLE_USERS1") // ②
@PreAuthorize("hasRole(USERS)") // ③
public Object get(@PathVariable("id") Integer id) {
return "receive - " + id ;
}接收一个String[] 数组,可以定义多个角色。接收一个String[] 数组,可以定义多个角色。 可以使用SpEL表达式。本篇内容只演示基于@PreAuthorize注解的权限控制,其它两个都非常简单不做演示。企商汇
PreAuthorize注解使用
该注解用于指定方法访问控制表达式的注释,该表达式将被计算以确定是否允许方法调用。默认支持的如下表达式:

示例1:
访问该接口必须具备USERS角色。
@PreAuthorize("hasRole(USERS)")
public Object get(@PathVariable("id") Integer id) {
return "receive - " + id ;
}示例2:
访问该接口只要具有其中任意一种角色即可。
@PreAuthorize("hasAnyRole(USERS, ADMIN)")
public Object get(@PathVariable("id") Integer id) {
return "receive - " + id ;
}示例3:
访问该接口必须拥有bus:news:see权限。
@PreAuthorize("hasAuthority(bus:news:see)")
public Object get(@PathVariable("id") Integer id) {
return "receive - " + id ;
}实例4:
该接口只要拥有如下任意一个权限即可。
@PreAuthorize("hasAnyAuthority(bus:news:see, bus:news:write)")
public Object get(@PathVariable("id") Integer id) {
return "receive - " + id ;
}注意:这里的hasRole和hasAuthority区别?
权限认证使用的 表达式根对象的基类是SecurityExpressionRoot。该基类中实现了相应方法的调用
public abstract class SecurityExpressionRoot implements SecurityExpressionOperations {
private String defaultRolePrefix = "ROLE_";
@Override
public final boolean hasRole(String role) {
return hasAnyRole(role);
}
@Override
public final boolean hasAnyRole(String... roles) {
return hasAnyAuthorityName(this.defaultRolePrefix, roles);
}
@Override
public final boolean hasAuthority(String authority) {
return hasAnyAuthority(authority);
}
@Override
public final boolean hasAnyAuthority(String... authorities) {
return hasAnyAuthorityName(null, authorities);
}
private boolean hasAnyAuthorityName(String prefix, String... roles) {
Set
for (String role : roles) {
// 拼接ROLE_前缀
String defaultedRole = getRoleWithDefaultPrefix(prefix, role);
if (roleSet.contains(defaultedRole)) {
return true;
}
}
return false;
}
}通过上面的源码知道,不管是hasRole还是hasAuthority最终都是调用的hasAnyAuthorityName方法,而hasRole方法拼接ROLE_前缀。
总结:业务接口Controller权限控制个各种方式。相关文章
电脑系统安装教程(简明易懂的教程,助你快速掌握电脑系统安装技巧)
摘要:在如今数字化时代,电脑系统安装是每个电脑用户都会面临的一个重要问题。无论是新购买的电脑还是需要重装系统的旧电脑,正确地安装操作系统是确保电脑正常运行的关键。为了帮助读者解决这一问题...2025-11-05
近年来,随着经济水平的提高,大众也提高了医美的市场认知和使用意愿,越来越多人开始接受甚至主动接触医美。从2013年起,国内医美互联网企业涌现市场,今天我们就来聊聊医美行业短域名代表——美呗meb.co2025-11-05
如何抢注过期域名?域名抢注哪个平台好?域名过期后,什么时候抢注成功率更高?关于域名抢注的问题,小编之前也是反复在强调的,毕竟对于刚入米市的朋友,他们失去先天优势,想获取好域名,目前成本最低、最便捷的方2025-11-05
天下武功,无坚不摧,唯快不破!学习一个技术,通常只接触了零散的技术点,没有在脑海里建立一个完整的知识框架和架构体系,没有系统观。这样会很吃力,而且会出现一看好像自己会,过后就忘记,一脸懵逼。跟着「码哥2025-11-05- 摘要:在日常使用电脑的过程中,我们时常会遇到各种问题,其中之一就是登陆错误。这种情况往往让人感到困惑和烦恼,但幸运的是,电脑管家提供了一键重启功能,能够帮助我们轻松解决登陆错误问题,让使...2025-11-05
0x01:背景有时在做开发的时候需要记录每个任务执行时间,或者记录一段代码执行时间,最简单的方法就是打印当前时间与执行完时间的差值,然后这样如果执行大量测试的话就很麻烦,并且不直观,如果想对执行的时间2025-11-05

最新评论