springSecurity权限控制

news2024/12/12 21:38:05

权限控制:不同的用户可以使用不同的功能。

我们不能在前端判断用户权限来控制显示哪些按钮,因为这样,有人会获取该功能对应的接口,就不需要通过前端,直接发送请求实现功能了。所以需要在后端进行权限判断。(前端防君子,后端防小人。

授权流程:springSecurity会默认使用FilterSecurityInterceptor进行权限校验,会从SecurityContextHolder中获取authentication,获取权限信息进行判断。

所以需要我们做的就是把用户的权限信息存入authentication。

那么SecurityContextHolder中的权限信息是从哪里获取的呢,前面SecurityContextHolder中的认证用户信息是从redis中获取的,权限信息也一样。

我们先说说权限控制的方案:1、springSecurity提供注解;2、配置

注解权限控制是我们经常用的,我就只说这个方案了。

使用权限控制注解,需要在SecurityConfig配置类中开启配置:

@EnableGlobalMethodSecurity(prePostEnabled = true)

@Configuration
//开启权限控制注解
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
     .....
}

我们能用的权限控制注解有很多,但真正经常用的只有@PreAuthorize就是在访问之前进行权限判断。写在controller层的请求方法上。

@PreAuthorize("hasAuthority('test')")

这里其实是去调用hasAuthority方法去判读权限,返回true即有权限。test为权限名

@RestController
@RequestMapping
public class HelloController {
    @GetMapping("/hello")
    //这里其实是去调用hasAuthority方法去判读权限,返回true即有权限.test为权限名,这里只能填一个权限
    @PreAuthorize("hasAuthority('test')")
    public String hello(){
        return "hello";
    }

至于 权限名的定义和权限内容的定义 在后面定义。

注解类方法:

@PreAuthorize("hasAuthority('权限名')")

除了前面用的hasAuthority方法外,还有其他的校验方法,当然我们也可以自定义校验方法。

  hasAuthority(‘’)方法:只能填一个权限。

  hasAnyAuthority(‘’,’’,’’)方法:可以传入多个权限,其中用户有任意一个权限都可以访问。

  hasRole(‘’)方法:要求有对应角色才可以访问。它内部会把我们传入的角色参数拼接上 ROLE_ 后在去比较,所以需要对用户的权限也要有 ROLE_ 这个前缀。

  hasAnyRole(‘’,’’,’’)方法:要求有对应任意角色才可以访问。它内部也会把我们传入的角色参数拼接上 ROLE_ 后在去比较,所以需要对用户的权限也要有 ROLE_ 这个前缀。

同时权限是实体类User类的属性:

@Data
@NoArgsConstructor
//@AllArgsConstructor
public class LoginUser implements UserDetails {

    //需要定义User对象来封装用户信息。
    private User user;

    //该用户的权限信息
    private List<String> permissions;
    public LoginUser(User user, List<String> permissions) {
        this.user = user;
        this.permissions = permissions;
    }

    //问题:当我们把logUser存入redis中时,redis默认不会把SimpleGrantedAuthority对象序列化。
    //解决:我们不需要把SimpleGrantedAuthority存入redis,我们只需把权限信息permissions存入即可
    //通过permissions反序列化即可获取authorities,所以需要忽略SimpleGrantedAuthority,不要对它序列化
    @JSONField(serialize = false)
    private List<SimpleGrantedAuthority> authorities;
    @Override //实际springSecurity获取权限信息是调用的该方法,重写该方法。
    public Collection<? extends GrantedAuthority> getAuthorities() {
        //优化:如果每次获取权限都进行集合转换,有点浪费。我们只第一次去集合转换,后续获取直接返回之前转换好的
        //即把List<SimpleGrantedAuthority> authorities定义为成员变量。
        if(authorities!=null){
            return authorities;
        }
        authorities = permissions.stream()
                .map(SimpleGrantedAuthority::new)
                .collect(Collectors.toList());
        return authorities;
    }
}

然后去数据库中查询用户权限:

到数据库中查询权限信息:

RBAC权限模型(Role-Based Access Control):基于角色的权限控制。这是目前最常被开发者使用也是相对易用、通用权限模型。

在数据库中,我们会创建一个用户表,一个权限表(记录着权限功能说明和权限名),一个用户可以有多个权限,不好表达,所以我们又引入了一个角色表,里面有很多角色,在创建个角色权限管理表,每种角色对应不同的多种功能,为角色赋予不同的权限。比如:图书馆管理系统中的角色:图书管理员(权限:添加、查询、删除等等);借阅者(权限:查询、借阅)。同时,一个用户可能会有多种身份,需要将用户与角色关联起来。

这就是RBAC模型(最少都是5张表)

5表联合查询用户权限:role为角色表,menu为菜单表(可以理解为权限表) 

<mapper namespace="org.example.springSecurity.mapper.MenuMapper">
    <select id="selectPermsByUserId" resultType="java.lang.String">
        select
        distinct m.perms
        from sys_user_role ur
        Left join `sys_role` r on ur.role_id = r.id
        Left join `sys_role_menu` rm on ur.role_id = rm.role_id
        Left join `sys_menu` m on m.id = rm.menu_id
        where
        user_id = #{userId}
        and r.status = 0
        and m.status = 0
    </select>
</mapper>

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2256838.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

李飞飞的生成式3D场景,对数字孪生的未来影响几何?

大家好&#xff0c;我是日拱一卒的攻城师不浪&#xff0c;致力于技术与艺术的融合。这是2024年输出的第47/100篇文章。 前言 这两天&#xff0c;AI界的教母李飞飞团队重磅发布了空间智能生成式AI大模型。 仅通过一张图片就能够生成一个可操作和交互的3D空间场景。 空间智能的…

意图识别模型使用 基于BERT的对话意图和槽位联合识别 CPU运行BERT模型-亲测成功

意图识别模型使用 基于BERT的对话意图和槽位联合识别 CPU运行BERT模型-亲测成功 我们在开发AI-Agent智能体时&#xff0c;通常会使用提示词工程设置场景的带入&#xff0c;在实际项目中会有很多场景&#xff0c;如果所有提示词都放一起就会超过Token限制&#xff0c;则不得不拆…

OSG开发笔记(三十七):OSG基于windows平台msvc2017x64编译器官方稳定版本OSG3.4.1搭建环境并移植Demo

​若该文为原创文章&#xff0c;未经允许不得转载 本文章博客地址&#xff1a;https://blog.csdn.net/qq21497936/article/details/144258047 各位读者&#xff0c;知识无穷而人力有穷&#xff0c;要么改需求&#xff0c;要么找专业人士&#xff0c;要么自己研究 长沙红胖子Qt…

《毛泽东思想和中国特色社会理论概述》课程报告Latex版本

所需要的图片: 源码(可运行): \documentclass[12pt]{article} \usepackage{ctex} \usepackage{graphicx} \usepackage{booktabs} \usepackage{titlesec} \usepackage{geometry} \usepackage{float} \usepackage{tabularx} \usepackage{enumitem} …

2024.12.6——攻防世界PHP2

知识点&#xff1a;目录扫描 代码审计 传参知识点补充&#xff1a; 后缀名为.phps的文件出现在无法使用web浏览器查看php源代码的情况下&#xff0c;.phps文件就是php的源代码文件&#xff0c;通常用于提供给用户&#xff08;访问者&#xff09;查看php代码&#xff0c;因为用…

OSI模型及各层缺陷

1&#xff0e;TCP/IP概述 &#xff08;1&#xff09;TCP/IP基本结构 TCP/IP是一组Internet协议&#xff0c;不但包括TCP和IP两个关键协议&#xff0c;还包括其他协议&#xff0c;如UDP、ARP、ICMP、Telnet和FTP等。TCP/IP的设计目标是使不同的网络互相连接&#xff0c;即实现互…

【论文阅读】Fifty Years of the ISCA: A Data-Driven Retrospective

学习体会&#xff1a; ISCA会议近五十年文章分析, 了解论文热点方向, 处理器依旧是热点! AI和并行是大趋势, 做XPU相关目前来说还是热点~ 摘录自原文 摘录: 数据来源和分析方法&#xff1a; 作者收集了 ACM 数字图书馆中所有 ISCA 论文&#xff0c;并使用 DBLP、Google Schol…

什么是MMD Maximum Mean Discrepancy 最大均值差异?

9多次在迁移学习看到了&#xff0c;居然还是Bernhard Schlkopf大佬的论文&#xff0c;仔细看看。 一.什么是MMD&#xff1f; 1. MMD要做什么&#xff1f; 判断两个样本&#xff08;族&#xff09;是不是来自于同一分布 2.怎么做&#xff1f;&#xff08;直观上&#xff09;…

LDR6500:音频双C支持,数字与模拟的完美结合

在当今数字化快速发展的时代&#xff0c;音频设备的兼容性和性能成为了用户关注的重点。LDR6500&#xff0c;作为乐得瑞科技精心研发的USB Power Delivery&#xff08;PD&#xff09;协议芯片&#xff0c;凭借其卓越的性能和广泛的应用兼容性&#xff0c;为音频设备领域带来了新…

Leetcode 每日一题 1.两数之和

目录 问题描述 示例 示例 1 示例 2 示例 3 提示 解决方案 算法思路 过题图片 代码实现 复杂度分析 注意事项 题目链接 结论 问题描述 给定一个整数数组 nums 和一个目标值 target&#xff0c;请你找出数组中和为目标值的那两个整数&#xff0c;并返回它们的数组下…

【萤火工场CEM5826-M11测评】Arduino 采集雷达模块数据与串口绘图

【萤火工场CEM5826-M11测评】Arduino 采集雷达模块数据与串口绘图 当采用串口输出模式时&#xff0c;雷达检测到运动时&#xff0c;则输出 v0.0km/h, str1234 字样&#xff1b; v 表示目标速度大小&#xff0c;str 表示信号强度&#xff1b; 当雷达检测不到目标时&#xff0c…

【C++】选择排 序算法分析与扩展

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;代码回顾&#x1f4af;选择排序的算法流程&#x1f4af;代码详解外层循环初始化最小值内层循环比较与更新元素交换 &#x1f4af;选择排序的特性时间复杂度空间复杂度稳定性…

3D 生成重建024-LGM第一个开源的3D生成大模型!

3D 生成重建024-LGM第一个开源的3D生成大模型 文章目录 0 论文工作1 论文方法2 实验效果 0 论文工作 这篇论文介绍了一种名为LGM&#xff08;大型多视角高斯模型&#xff09;的新方法&#xff0c;用于从单视角图像或文本提示生成高分辨率的三维内容。该方法的核心思想是双重的…

微信 创建小程序码-有数量限制

获取小程序码&#xff1a;小程序码为圆图&#xff0c;有数量限制。 目录 文档 接口地址 功能描述 注意事项 请求参数 对接 获取小程序码 调用获取 小程序码示例 总结 文档 接口地址 https://api.weixin.qq.com/wxa/getwxacode?access_tokenaccess_token 功能描述 …

日志基础示例python和c++

文章目录 0. 引言1. python2. c 0. 引言 本文主要记录python版本和c版本常用的日志基础示例。 1. python python版本常用的是logging库&#xff0c;结合colorlog库&#xff0c;可根据不同日志级别打印不同颜色的日志&#xff0c;为了便于分析问题&#xff0c;还添加了日志保…

泷羽sec学习打卡-brupsuite4

声明 学习视频来自B站UP主 泷羽sec,如涉及侵权马上删除文章 笔记的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都 与本人无关,切莫逾越法律红线,否则后果自负 关于brupsuite的那些事儿-proxy proxyInterceptHTTP history/WebSocket history&#xff08;历史记录&a…

喜报!极限科技(INFINI Labs)通过国家高新技术企业认定

2024 年 10 月 29 日&#xff0c;国家高新技术企业认定管理工作网公示了北京市认定机构 2024 年认定报备的第一批高新技术企业备案名单&#xff0c;极限数据&#xff08;北京&#xff09;科技有限公司 顺利通过本次高新技术企业评审&#xff0c;并获得 国家级“高新技术企业”认…

STM32 USART串口通信 综合练习

USART&#xff08;通用同步/异步串行接收/发送器&#xff09;串口通信具有以下特点&#xff1a; 全双工操作&#xff1a;设备之间可以同时进行数据的发送和接收。异步通信&#xff1a;不需要共同的时钟信号&#xff0c;双方设备有各自的时钟。单端信号&#xff1a;使用一根线传…

Linux - 进程等待和进程替换

进程等待 前面我们了解了如果父进程没有回收子进程, 那么当子进程接收后, 就会一直处于僵尸状态, 导致内存泄漏, 那么我们如何让父进程来回收子进程的资源. waitpid 我们可以通过 Linux 提供的系统调用函数 wait 系列函数来等待子进程死亡, 并回收资源. #include <sys/t…

虚拟主机怎么选哪家的性价比高

选择虚拟主机不能只看价格&#xff0c;还要看质量和服务&#xff0c;稳定快速的虚拟主机再加上优质的售后服务&#xff0c;才可令网站顺利运行&#xff0c;站长才无后顾之忧。 选虚拟主机或云服务器还是要选大牌主机商的产品比较好&#xff0c;质量和服务更有保障&#xff0c;例…