文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Spring Security权限控制系列(六)

2024-12-01 16:33

关注

环境:Springboot2.4.12 + Spring Security 5.4.9

本篇主要内容:

  1. 业务接口权限认证

上一篇:《​​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 ;
}
  1. 接收一个String[] 数组,可以定义多个角色。
  2. 接收一个String[] 数组,可以定义多个角色。
  3. 可以使用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<String> roleSet = getAuthoritySet();
for (String role : roles) {
// 拼接ROLE_前缀
String defaultedRole = getRoleWithDefaultPrefix(prefix, role);
if (roleSet.contains(defaultedRole)) {
return true;
}
}
return false;
}
}

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

总结:

来源:今日头条内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯