springSecurity权限控制

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

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

授权流程: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>

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

力扣打卡9:重排链表

链接&#xff1a;143. 重排链表 - 力扣&#xff08;LeetCode&#xff09; 这是一道操作链表的题。按照要求&#xff0c;我们可以将解题的步骤分成三步。 1.找链表中间结点&#xff08;我使用了快慢指针寻找&#xff09;&#xff0c;并断开。 2.现在有2链表&#xff0c;将后段…

计算机键盘的演变 | 键盘键名称及其功能 | 键盘指法

注&#xff1a;本篇为 “键盘的演变及其功能” 相关几篇文章合辑。 英文部分机翻未校。 The Evolution of Keyboards: From Typewriters to Tech Marvels 键盘的演变&#xff1a;从打字机到技术奇迹 Introduction 介绍 The keyboard has journeyed from a humble mechanical…

【Appium报错】安装uiautomator2失败

目录 1、通过nmp安装uiautomator2&#xff1a;失败 2、通过 Appium 的平台直接安装驱动程序 3、通过pip 来安装 uiautomator2 1、通过nmp安装uiautomator2&#xff1a;失败 我先是通过npm安装的uiautomator2&#xff0c;也显示已经安装成功了&#xff1a; npm install -g …

SSM整合原理实战案例《任务列表案例》

一、前端程序搭建和运行: 1.整合案例介绍和接口分析: (1).案例功能预览: (2).接口分析: 学习计划分页查询 /* 需求说明查询全部数据页数据 请求urischedule/{pageSize}/{currentPage} 请求方式 get 响应的json{"code":200,"flag":true,"data&…

Chrome扩展程序开发示例

项目文件夹内文件如下&#xff1a; manifest.json文件内容&#xff1a; {"manifest_version": 3,"name": "我的法宝","description": "我的有魔法的宝贝","version": "1.0","icons": {"…

石头剪子布

石头剪子布 C语言实现C实现Java实现Python实现 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 石头剪子布&#xff0c;是一种猜拳游戏。起源于中国&#xff0c;然后传到日本、朝鲜等地&#xff0c;随着亚欧贸易的不断发展它传到了欧洲&…

RabbitMQ核心概念及工作流程 + AMQP

文章目录 一. RabbitMQ核心概念1. Producer, Consumer, Broker2. Connection和Channel3. Virtual host4. Queue5. Exchange 二. RabbitMQ的工作流程三. AMQP四. web界面操作对用户操作对虚拟机操作 一. RabbitMQ核心概念 RabbitMQ是⼀个消息中间件, 也是⼀个⽣产者消费者模型.…

js循环导出多个word表格文档

文章目录 js循环导出多个word表格文档一、文档模板编辑二、安装依赖三、创建导出工具类exportWord.js四、调用五、效果图js循环导出多个word表格文档 结果案例: 一、文档模板编辑 二、安装依赖 // 实现word下载的主要依赖 npm install docxtemplater pizzip --save// 文件操…

字节高频算法面试题:小于 n 的最大数

问题描述&#xff08;感觉n的位数需要大于等于2&#xff0c;因为n的位数1的话会有点问题&#xff0c;“且无重复”是指nums中存在重复&#xff0c;但是最后返回的小于n最大数是可以重复使用nums中的元素的&#xff09;&#xff1a; 思路&#xff1a; 先对nums倒序排序 暴力回…

windows11 实现Hyper-v ubuntu22.04 GPU虚拟化(GPU分区、GPU-P)教程

注:1、本文提到的vGPU、GPU分区都是指的微软的GPU-P技术。 2、在实操过程中,发现网上的很多文章要么记录不全,要么描述不清楚,导致的结果就是根本没法走通。希望通过该文章能解决小伙伴们在实操中遇到的一些坑。 前提说明 1、物理机需要支持SR-IOV,在主板BIOS中可以通过…

AndroidStudio-常见界面控件

一、Button package com.example.review01import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.widget.Button import android.widget.TextViewclass Review01Activity : AppCompatActivity() {override fun onCreate(savedInstanceStat…

沐风老师3DMAX摄相机阵列插件使用方法

3DMAX摄相机阵列插件&#xff0c;从网格对象或样条线的顶点法线快速创建摄相机阵列。该插件从网格的顶点或样条线的节点获取每个摄影机的位置和方向。 3DMAX摄相机阵列插件支持目前3dMax主流的物理相机、标准相机、VRay物理相机。 【版本要求】 3dMax 2015及更高版本 【安装方…

记录一下,解决js内存溢出npm ERR! code ELIFECYCLEnpm ERR! errno 134 以及 errno 9009

项目是个老项目&#xff0c;依赖包也比较大&#xff0c;咱就按正常流程走一遍来详细解决这个问题&#xff0c;先看一下node版本&#xff0c;我用的是nvm管理的&#xff0c;详细可以看我的其他文章 友情提醒&#xff1a;如果项目比较老&#xff0c;包又大&#xff0c;又有一些需…

飞飞5.4游戏源码(客户端+服务端+工具完整源代码+5.3fix+5.4patch+数据库可编译进游戏)

飞飞5.4游戏源码&#xff08;客户端服务端工具完整源代码5.3fix5.4patch数据库可编译进游戏&#xff09; 下载地址&#xff1a; 通过网盘分享的文件&#xff1a;【源码】飞飞5.4游戏源码&#xff08;客户端服务端工具完整源代码5.3fix5.4patch数据库可编译进游戏&#xff09; 链…

springboot的 nacos 配置获取不到导致启动失败及日志不输出问题

前言 问题 1. 本地启动应用时&#xff0c;一切正常&#xff0c;但是部署 docker 后&#xff0c;会因为获取不到 nacos 中的配置导致服务启动失败。 2.当 docker 中的服务一直重启&#xff0c;可能会突然某一次启动成功&#xff0c;之后只要不重新构建 docker 镜像&am…

Docker Compose实战一( 轻松部署 Nginx)

通过过前面的文章&#xff08;Docker Compose基础语法&#xff09;你已经掌握基本语法和常用指令认识到Docker Compose作为一款强大工具的重要性&#xff0c;它极大地简化了多容器Docker应用程序的部署与管理流程。本文将详细介绍如何使用 Docker Compose 部署 Nginx&#xff0…

汽车IVI中控OS Linux driver开发实操(二十八):回声消除echo cancellation和噪声消除Noise reduction

概述: 在当今高度互联的世界中,清晰的实时通信比以往任何时候都更重要。在远程团队会议期间,没有什么能像回声一样打断对话。当说话者听到他们的声音回响时,可能会分散注意力,甚至无法理解对话。即使是很小的回声也会产生很大的影响,仅仅25毫秒的振幅就足以造成声音干扰…

计算机毕设-基于springboot的实践性教学系统设计与实现(附源码+lw+ppt+开题报告)

博主介绍&#xff1a;✌多个项目实战经验、多个大型网购商城开发经验、在某机构指导学员上千名、专注于本行业领域✌ 技术范围&#xff1a;Java实战项目、Python实战项目、微信小程序/安卓实战项目、爬虫大数据实战项目、Nodejs实战项目、PHP实战项目、.NET实战项目、Golang实战…

UE5 猎户座漂浮小岛 09 移动能力 角色属性

UE5 猎户座漂浮小岛 09 移动能力 角色属性&#xff08;1&#xff09; 1.移动能力 1.1 加速跑 BlendSpace&#xff1a;混合空间 2.角色属性 2.1 行动点数 AP&#xff1a;Action Point Max AP&#xff1a;Max Action Point AP CPS&#xff1a;Action Point Consume Per Sec…

低级爬虫实现-记录HCIP云架构考试

因工作需要考HCIP云架构&#xff08;HCIP-Cloud Service Solution Architect&#xff09;证书, 特意在淘宝上买了题库&#xff0c; 考过了。 事后得知自己被坑了&#xff0c; 多花了几十大洋。 所以想着在授权期内将题库“爬”下来&#xff0c; 共享给大家。 因为整个过程蛮有…