当前位置: 首页 > news >正文

【SpringSecurity】三、访问授权

文章目录

  • 1、配置用户权限
  • 2、针对URL授权
  • 3、针对方法的授权

1、配置用户权限

继续上一章,给在内存中创建两个用户配置权限。配置权限有两种方式:

  • 配置roles
  • 配置authorities
//哪个写在后面哪个起作用
//角色变成权限后会加一个ROLE_前缀,比如ROLE_teacher
UserDetails user2 = User.builder().username("thomas").password(passwordEncoder().encode("123456")).authorities("teacher:add","teacher:update").roles("teacher").build();UserDetails user2 = User.builder().username("thomas").password(passwordEncoder().encode("123456")).roles("teacher").authorities("teacher:add","teacher:update").build();

以上两种写法,顺序不同,获取当前登录用户时,得到的权限值也不一样。总结就是:

  • 如果给一个用户同时配置roles和authorities,哪个方法后面调用哪个起作用
  • 配置roles时,权限名会加上ROLE_

当然,从代码层来说,角色和权限并没太大区别,并特别是在Spring Security中。

2、针对URL授权

未做授权时,默认登录成功的用户可以访问所有资源(调任意一个接口),但有的接口只能允许管理员调用,因此,这里需要再实现授权功能。先看针对URL授权,即哪些权限可以访问哪些URL。新建配置类MyWebSecurityConfig,继承抽象类WebSecurityConfigurerAdapter,重写configure(HttpSecurity http)方法

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests()  //授权请求.anyRequest()   //任何请求.denyAll();  //拒绝所有请求访问//.permitAll(); //允许所有请求}
}

在这里插入图片描述
放开登录认证页面:

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests()  //授权请求.anyRequest()   //任何请求.denyAll();  //拒绝所有请求访问//.permitAll(); //允许所有请求http.formLogin().permitAll();  //放开表单登录}
}

针对不同的url,要求拥有不同的权限才能访问,实现如下:

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().mvcMatchers("/student/**").hasAnyAuthority("ROLE_student", "ROLE_teacher")   //有任一权限就能访问上面的url,形参是可变长字符串.mvcMatchers("/teacher/**").hasAuthority("ROLE_teacher") //必须有这个权限才能访问上面的url.anyRequest() //任何请求.authenticated();  //都需要登录,即那些没有单独设置权限的url,仅需登录就能访问http.formLogin().permitAll();}
}

关于URL匹配,可选框架中的以下方法:

  • mvcMatchers() (优先)
  • regexMatchers()
  • antMatchers()

关于校验是否有对应的权限,框架中的方法可选:

  • hasAuthority() 是否有单个权限
  • hasRole()
  • hasAnyAuthority() 是否有其中任一个权限
  • hasAnyRole()

还可以.access()写表达式:

.mvcMatchers("/admin/**")
.access("hasRole('teacher') or hasAuthority('admin:query')")
//里面用单引号,省的转义

3、针对方法的授权

上面是URL级别的授权,接下来进行方法级别的权限控制。先写一个增删改查的简单代码,方便后面测试。

测试素材代码:

//新建教师接口
public interface TeacherService {String add();String update();String delete();String query();
}
//实现接口
@Service
@Slf4j
public class TeacherServiceImpl implements TeacherService {@Overridepublic String add() {log.info("添加教师成功");return "添加教师成功";}@Overridepublic String update() {log.info("修改教师成功");return "修改教师成功";}@Overridepublic String delete() {log.info("删除教师成功");return "删除教师成功";}@Overridepublic String query() {log.info("查询教师成功");return "查询教师成功";}
}

简单补充下controller:

@RestController
@RequestMapping("/teacher")
public class TeacherController {@Resourceprivate TeacherService teacherService;@GetMapping("/query")public String queryInfo() {return teacherService.query();}@GetMapping("/add")public String addInfo() {return teacherService.add();}@GetMapping("/update")public String updateInfo() {return teacherService.update();}@GetMapping("/delete")public String deleteInfo() {return teacherService.delete();}
}

配置类中新建三个测试用户在内存中:

@Configuration
public class MySecurityUserConfig {@Beanpublic UserDetailsService userDetailService() {UserDetails user1 = User.builder().username("liu").password(passwordEncoder().encode("123456")).roles("student").build();UserDetails user2 = User.builder().username("Mr.liu").password(passwordEncoder().encode("123456")).roles("teacher").build();UserDetails user3 = User.builder().username("admin").password(passwordEncoder().encode("123456")).authorities("teacher:add", "teacher:update").build();//创建两个用户InMemoryUserDetailsManager userDetailsManager = new InMemoryUserDetailsManager();userDetailsManager.createUser(user1);userDetailsManager.createUser(user2);return userDetailsManager;}/** 从 Spring5 开始,强制要求密码要加密* @return*/@Beanpublic PasswordEncoder passwordEncoder(){//使用加密算法对密码进行加密return new BCryptPasswordEncoder();}}

Web安全配置适配器类:

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {//任何访问均需要认证http.authorizeRequests().anyRequest().authenticated();http.formLogin().permitAll();}
}

进行方法级别的控制

首先,加上启动全局方法安全的注解 @EnableGlobalMethodSecurity(prePostEnabled = true)

//@Configuration
//@EnableGlobalMethodSecurity注解中有@Configuration注解,所以这里注掉了就
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {//任何访问均需要认证http.authorizeRequests().anyRequest().authenticated();//登录放行http.formLogin().permitAll();}
}

@EnableGlobalMethodSecurity(prePostEnabled = true)中的prePostEnabled是预授权和后授权,预授权即访问前判断有无权限,后授权则是方法执行完以后才判断是否有权限,后授权的使用场景比较少。接下来修改要控制访问的方法,使用 前置授权注解@PreAuthorize

@Service
@Slf4j
public class TeacherServiceImpl implements TeacherService {@Override@PreAuthorize("hasAuthority('teacher:add') OR hasRole('teacher')")public String add() {log.info("添加教师成功");return "添加教师成功";}@Override@PreAuthorize("hasAuthority('teacher:update')")public String update() {log.info("修改教师成功");return "修改教师成功";}@Override@PreAuthorize("hasAuthority('teacher:delete')")public String delete() {log.info("删除教师成功");return "删除教师成功";}@Override@PreAuthorize("hasRole('teacher')")public String query() {log.info("查询教师成功");return "查询教师成功";}
}

此时,登录有不同权限的不同角色,其只能访问对应有权限的方法。

在这里插入图片描述

注意,这里控制的是对方法的访问,仅仅是限制对方法的访问。

	@GetMapping("/delete")public String deleteInfo() {return teacherService.delete();}

改为:

	@GetMapping("/delete")public String deleteInfo() {int a = 10log.info("进入了TeacherController,a={}" , a);return teacherService.delete();}

登录学生账户,访问delete接口,此时结果仍然403,但控制台可以看到在到达被限制权限的方法前的代码是可以访问的:

在这里插入图片描述

当然,@PreAuthorize注解也可以写在Controller中的方法上,此时上面的int a = 10自然就访问不到了。

小总结:

在这里插入图片描述

相关文章:

【SpringSecurity】三、访问授权

文章目录 1、配置用户权限2、针对URL授权3、针对方法的授权 1、配置用户权限 继续上一章,给在内存中创建两个用户配置权限。配置权限有两种方式: 配置roles配置authorities //哪个写在后面哪个起作用 //角色变成权限后会加一个ROLE_前缀,比…...

你对SPA单页面的理解,它的优缺点分别是什么?如何实现SPA应用呢?

一、什么是SPA SPA(single-page application),翻译过来就是单页应用SPA是一种网络应用程序或网站的模型,它通过动态重写当前页面来与用户交互,这种方法避免了页面之间切换打断用户体验在单页应用中,所有必…...

【LeetCode75】第三十七题 二叉树中的最长交错路径

目录 题目: 示例: 分析: 代码: 题目: 示例: 分析: 给我们一棵二叉树,问我们在这棵树里能找到的最长交错路径。最长交错路径就是在二叉树里一左一右一左一右这样走,最…...

百度Apollo学习心得:探索自动驾驶技术的前沿之旅

文章目录 前言一、理论学习与实践结合二、多方资源的整合利用三、团队合作与交流分享四、持续学习与创新思维总结 前言 百度Apollo是一项引领自动驾驶技术发展的开放平台,通过深度学习、感知与决策、定位与控制等关键技术,为开发者提供了丰富的工具和资…...

kafka原理之springboot 集成批量消费

前言 由于 Kafka 的写性能非常高&#xff0c;因此项目经常会碰到 Kafka 消息队列拥堵的情况。遇到这种情况&#xff0c;我们可以通过并发消费、批量消费的方法进行解决。 一、新建一个maven工程&#xff0c;添加kafka依赖 <dependency><groupId>org.springframe…...

【GeoDa实用技巧100例】024:geoda计算全局(局部)莫兰指数Moran‘s I,LISA聚类地图,显著性地图

严重声明:本文及专栏《GeoDa空间计量案例教程100例》为CSDN博客专家刘一哥GIS原创,原文及专栏地址为:https://blog.csdn.net/lucky51222/category_12373659.html,谢绝转载或爬取!!! 文章目录 一、计算全局(或局部)单变量莫兰指数I1. 加载实验数据2. 加载权重矩阵3. 创建…...

Java进阶(7)——手动实现LinkedList 内部node类的实现 增删改查的实现 toString方法 源码的初步理解

目录 引出从ArrayList到Linkedlist手动实现ArrayList从ArrayList到LinkedList 总体设计Node类Node的方法&#xff1a;根据index找node 增删改查的实现增加元素删除元素修改元素查询元素 toString方法完整代码List接口类LinkedList的实现测试类 总结 引出 1.linkedList的节点&am…...

CPU总线的理解

目录 CPU总线CPU总线是什么&#xff1f;CPU总线可以分为前端部分和后端部分吗&#xff1f; CPU总线 CPU总线是什么&#xff1f; CPU总线&#xff08;Central Processing Unit Bus&#xff09;是计算机硬件中的一个重要组成部分&#xff0c;它是连接CPU和其他硬件组件的通道。…...

Spring Boot 中的 AOP,到底是 JDK 动态代理还是 Cglib 动态代理

大家都知道&#xff0c;AOP 底层是动态代理&#xff0c;而 Java 中的动态代理有两种实现方式&#xff1a; 基于 JDK 的动态代理 基于 Cglib 的动态代理 这两者最大的区别在于基于 JDK 的动态代理需要被代理的对象有接口&#xff0c;而基于 Cglib 的动态代理并不需要被代理对…...

记录一下在工作中使用 LayUI bug的问题

前言&#xff1a; LayUI是一个很老的框架了&#xff0c;经常会碰到一些 bug。不过由于他的轻量级&#xff0c;仍然有一些项目在使用。解决这些 bug 可能会对大家产生一些意义。 layui中 slect form表单元素 不美化显现的问题 layui中美化的表单元素 在渲染完成要添加 form.re…...

手机自动无人直播,实景无人直播真的有用吗?

继数字人直播之后&#xff0c;手机自动直播开始火热了起来&#xff0c;因为其门槛低&#xff0c;成本低&#xff0c;一部手机一个账号就可以实现直播&#xff0c;一时深受广大商家的好评。那么&#xff0c;手机自动无人直播究竟是如何实现自动直播的呢&#xff1f; 在传统的直…...

python 面试题--2(15题)

目录 1.解释Python中的 GIL&#xff08;全局解释器锁&#xff09;是什么&#xff0c;它对多线程编程有什么影响&#xff1f; 2.Python中的装饰器是什么&#xff1f;如何使用装饰器&#xff1f; 3.解释Python中的迭代器和生成器的区别。 4.什么是Python中的列表解析&#xf…...

kafka复习:(11)auto.offset.reset的默认值

在ConsumerConfig这个类中定义了这个属性的默认值&#xff0c;如下图 也就是默认值为latest,它的含义是&#xff1a;如果没有客户端提交过offset的话&#xff0c;当新的客户端消费时&#xff0c;把最新的offset设置为当前消费的offset. 默认是自动提交位移的&#xff0c;每5秒…...

【javaweb】学习日记Day7 - Mysql 数据库 DQL 多表设计

之前学习过的SQL语句笔记总结戳这里→【数据库原理与应用 - 第六章】T-SQL 在SQL Server的使用_Roye_ack的博客-CSDN博客 目录 一、DQL 数据查询 1、基本查询 2、条件查询 3、分组查询 &#xff08;1&#xff09;聚合函数 ① count函数 ② max min avg sum函数 &…...

线程的生命周期

线程的生命周期 与人有生老病死一样&#xff0c;线程也同样要经历开始&#xff08;等待&#xff09;、运行、挂起和停止四种不同的状态。这四种状态都可以通过Thread类中的方法进行控制。下面给出了Thread类中和这四种状态相关的方法。 // 开始线程 public void start( ); …...

GAN | 论文精读 Generative Adversarial Nets

提出一个GAN &#xff08;Generative Adversarial Nets&#xff09; 1 方法 &#xff08;1&#xff09;生成模型G&#xff08;Generative&#xff09;&#xff0c;是用来得到分布的&#xff0c;在统计学眼里&#xff0c;整个世界是通过采样不同的分布得到的&#xff0c;生成…...

Yolo系列-yolov2

YOLO-V2 更快&#xff01;更强&#xff01; YOLO-V2-BatchNormalization BatchNormalization&#xff08;批归一化&#xff09;是一个常用的深度神经网络优化技术&#xff0c;它可以将输入数据进行归一化处理&#xff0c;使得神经网络更容易进行学习。在YOLOv2中&#xff0c;B…...

Linux下的系统编程——vim/gcc编辑(二)

前言&#xff1a; 在Linux操作系统之中有很多使用的工具&#xff0c;我们可以用vim来进行程序的编写&#xff0c;然后用gcc来生成可执行文件&#xff0c;最终运行程序。下面就让我们一起了解一下vim和gcc吧 目录 一、vim编辑 1.vim的三种工作模式 2.基本操作之跳转字符 &a…...

2023年国赛 高教社杯数学建模思路 - 案例:最短时间生产计划安排

文章目录 0 赛题思路1 模型描述2 实例2.1 问题描述2.2 数学模型2.2.1 模型流程2.2.2 符号约定2.2.3 求解模型 2.3 相关代码2.4 模型求解结果 建模资料 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 最短时…...

芯科科技推出专为Amazon Sidewalk优化的全新片上系统和开发工具,加速Sidewalk网络采用

芯科科技为Sidewalk开发提供专家级支持 中国&#xff0c;北京 - 2023年8月22日 – 致力于以安全、智能无线连接技术&#xff0c;建立更互联世界的全球领导厂商Silicon Labs&#xff08;亦称“芯科科技”&#xff0c;NASDAQ&#xff1a;SLAB&#xff09;今日在其一年一度的第四…...

Kotlin 丰富的函数特性

Kotlin 是一门基于 JVM 的现代编程语言&#xff0c;它提供了丰富的函数特性&#xff0c;使得编写简洁、灵活且可读性强的代码成为可能。以下是 Kotlin 函数的一些主要特性&#xff1a; 一、函数声明与调用 在 Kotlin 中&#xff0c;使用 fun 关键字来声明函数。函数声明的基本…...

Node.js怎么搭建HTTP服务器

在 Node.js 中搭建一个简单的 HTTP 服务器非常容易。以下是一个基本的示例&#xff0c;演示如何使用 Node.js 创建一个简单的 HTTP 服务器&#xff1a; // 导入 http 模块 const http require(http); // 创建一个 HTTP 服务器 const server http.createServer((req, res) …...

基于Redisson的联锁(MultiLock)

基于Redis的分布式MultiLock对象允许对Lock对象进行分组并将它们作为单个锁进行处理。每个RLock对象可能属于不同的Redisson实例。 如果获取的Redisson实例MultiLock崩溃&#xff0c;那么它可能永远挂在获取状态。为了避免这种情况&#xff0c;Redisson维护了一个锁看门狗&…...

人脸识别平台批量导入绑定设备的一种方法

因为原先平台绑定设备是通过一个界面进行人工选择绑定或一个人一个人绑定设备。如下&#xff1a; 但有时候需要在几千个里选择出几百个&#xff0c;那这种方式就不大现实了&#xff0c;需要另外一种方法。 目前相到可以通过导入批量数据进行绑定的方式。 一、前端 主要是显示…...

MySQL—MySQL的NULL值是怎么存放的

一、引言 1、MySQL数据存放在哪个文件&#xff1f; 创建一个数据库会产生三种格式的文件&#xff0c;分别是.opt格式、.frm格式、.ibd格式。 opt格式&#xff1a;用来存储当前数据库的默认字符集和字符校验规则。 frm格式&#xff1a;该文件是用来保存每个表的元数据信息的&…...

sql server删除历史数据

1 函数 datediff函数: DATEDIFF ( datepart , startdate , enddate )datepart的取值可以是year,quarter,Month,dayofyear,Day,Week,Hour,minute,second,millisecond startdate 是从 enddate 减去。如果 startdate 比 enddate 晚&#xff0c;返回负值。 2 例子 删除2023年以…...

目标检测项目中,使用python+xml.etree.ElementTree修改xml格式标注文件中的类别名称

需求&#xff1a; 数据集的数据增强中&#xff0c;有时需要将xml标注文件中的类别做修改为新类别&#xff0c;或者将几个类别合并为一个类别。 解决方法&#xff1a; 使用pythonimport xml.etree.ElementTree将xml标注文件中的类别名称做修改。代码如下&…...

最新域名和子域名信息收集技术

域名信息收集 1&#xff0e;WHOIS查询 WHOIS是一个标准的互联网协议&#xff0c;可用于收集网络注册信息、注册域名﹑IP地址等信息。简单来说&#xff0c;WHOIS就是一个用于查询域名是否已被注册及注册域名详细信息的数据库&#xff08;如域名所有人、域名注册商&#xff09;…...

C语言基础之——指针(上)

前言&#xff1a;小伙伴们又见面啦&#xff01;本期内容&#xff0c;博主将展开讲解有关C语言中指针的上半部分基础知识&#xff0c;一起学习起来叭&#xff01;&#xff01;&#xff01; 目录 一.什么是指针 二.指针类型 1.指针的解引用 2.指针-整数 三.野指针 1.野指针…...

构建 NodeJS 影院预订微服务并使用 docker 部署(04/4)

一、说明 构建一个微服务的电影网站&#xff0c;需要Docker、NodeJS、MongoDB&#xff0c;这样的案例您见过吗&#xff1f;如果对此有兴趣&#xff0c;您就继续往下看吧。 我们前几章的快速回顾 第一篇文章介绍了微服务架构模式&#xff0c;并讨论了使用微服务的优缺点。第二篇…...