Spring Security权限控制系列(六)

IT科技2025-11-05 06:29:5451

环境: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接口权限。b2b供应网

注意:并不是权限基于注解的权限控制只能应用到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) {

SetroleSet = getAuthoritySet();

for (String role : roles) {

// 拼接ROLE_前缀

String defaultedRole = getRoleWithDefaultPrefix(prefix, role);

if (roleSet.contains(defaultedRole)) {

return true;

}

}

return false;

}

}

通过上面的源码知道,不管是hasRole还是hasAuthority最终都是调用的hasAnyAuthorityName方法,而hasRole方法拼接ROLE_前缀。

总结:业务接口Controller权限控制个各种方式。
本文地址:http://www.bzuk.cn/html/038f31399648.html
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

全站热门

如何使用电脑自带工具查看CPU温度(一步步教你轻松监测CPU温度,确保电脑运行稳定)

掌握了这30道MySQL基础面试题,我成了面霸

一日一技:XPath 匹配如何忽略大小写?

.io域名频频高价成交 .io后缀发展前景如何?

微信文件大小限制解除所需时间(突破微信文件大小限制需要多久?)

我是Redis,MySQL大哥被我害惨了!

解决消息延迟和堆积问题

“分库分表”与“NewSQL”如何选择?

友情链接

滇ICP备2023006006号-33