使用Spring Security实现用户-角色-资源的权限控制

news2024/11/24 15:53:32

文章目录

    • 一、基于角色的请求控制
    • 二、加载用户角色信息
    • 三、角色与资源的关联
    • 四、测试角色权限控制
      • 1. 未登录用户访问受保护资源
      • 2. 登录用户访问受保护资源
      • 3. 角色不足的用户访问受保护资源(把前面改成.roles("USER"))
    • 五、自定义异常处理
      • 1. 自定义未授权处理器
      • 2. 注册自定义异常处理器
    • 六、总结

在Web应用的开发中,权限管理是必不可少的一环。继上次分享了基于 用户-权限-资源的权限控制后,这次我们来探讨如何通过Spring Security实现 用户-角色-资源的权限管理。

一、基于角色的请求控制

首先,我们需要根据不同的资源路径设置相应的角色要求。以下是安全配置的代码:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    // 开启授权保护
    http.authorizeHttpRequests(authorize -> authorize
            // 所有 /user/** 路径下的请求需要 ADMIN 角色
            .requestMatchers("/user/**").hasRole("ADMIN")
            // 对所有请求开启授权保护
            .anyRequest()
            // 已认证的请求自动被授权
            .authenticated());
    // 其他配置省略...
}

在这段代码中,我们通过hasRole("ADMIN")方法,指定访问/user/**路径的请求需要具备ADMIN角色。这样,我们就实现了基于角色的资源访问控制。

二、加载用户角色信息

接下来,我们需要为用户加载其对应的角色信息。在Spring Security中,可以通过实现UserDetailsService接口的loadUserByUsername方法:

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
    lambdaQueryWrapper.eq(User::getUsername, username);
    User user = userMapper.selectOne(lambdaQueryWrapper);
    if (user == null) {
        throw new UsernameNotFoundException(username);
    } else {
        return org.springframework.security.core.userdetails.User.withUsername(user.getUsername())
                .password(user.getPassword())
                .disabled(!user.getEnabled())
            	// 设置用户的凭据是否过期,false 表示凭据未过期
                .credentialsExpired(false)
            	// 设置账户是否被锁定,false 表示账户未锁定
                .accountLocked(false)
                // 为用户分配 ADMIN 角色
                .roles("ADMIN")
                .build();
    }
}

在这个方法中,我们:

  1. 从数据库中根据用户名查询用户信息。
  2. 如果用户存在,使用User.withUsername()方法构建一个UserDetails对象。
  3. 通过.roles("ADMIN")方法为用户分配ADMIN角色。

需要注意的是,Spring Security在处理角色时,会自动为角色名添加"ROLE_"前缀。因此,"ADMIN"角色实际上对应权限"ROLE_ADMIN"

三、角色与资源的关联

通过上述配置,我们实现了以下功能:

  • 用户:通过数据库加载,包含用户名、密码、是否启用等信息。
  • 角色:为用户分配特定的角色,例如ADMIN
  • 资源:指定哪些URL路径需要哪些角色才能访问。

当用户尝试访问受保护的资源时,Spring Security会根据用户的角色信息决定是否授权。

四、测试角色权限控制

以下是一些测试场景,帮助验证我们的权限控制是否正确。

1. 未登录用户访问受保护资源

当未登录的用户尝试访问/user/list时,会被重定向到登录页面,提示需要先进行身份认证。

image-20241008162750204

2. 登录用户访问受保护资源

使用具备ADMIN角色的用户登录后,尝试访问/user/list,应当能够正常访问。

image-20241008162040000

3. 角色不足的用户访问受保护资源(把前面改成.roles(“USER”))

如果登录的用户没有ADMIN角色,尝试访问/user/list时,会收到权限不足的提示,无法访问该资源。

image-20241008162212811

五、自定义异常处理

为了提升用户体验,我们可以自定义异常处理器,返回统一的JSON格式错误信息。

1. 自定义未授权处理器

public class MyAccessDeniedHandler implements AccessDeniedHandler {
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response,
                       AccessDeniedException accessDeniedException) throws IOException, ServletException {
        // 创建结果对象
        HashMap<String, Object> result = new HashMap<>();
        result.put("code", -1);
        result.put("message", "没有访问该资源的权限");

        // 转换成JSON字符串
        String json = JSON.toJSONString(result);

        // 返回响应
        response.setContentType("application/json;charset=utf-8");
        response.getWriter().println(json);
    }
}

2. 注册自定义异常处理器

http.exceptionHandling(exception -> {
    // 请求未认证的处理
    exception.authenticationEntryPoint(new MyAuthenticationEntryPoint());
    // 请求未授权的处理
    exception.accessDeniedHandler(new MyAccessDeniedHandler());
});

通过上述配置,当用户没有权限访问某个资源时,会返回自定义的JSON错误信息,方便前端进行处理。

六、总结

通过以上步骤,我们实现了基于用户-角色-资源的权限控制:

  • 用户:通过UserDetailsService加载用户信息,并为其分配ADMIN角色。
  • 角色:使用.roles("ADMIN")方法为用户指定角色。
  • 资源:通过requestMatchers("/user/**").hasRole("ADMIN")指定需要ADMIN角色才能访问的资源。

这种方式的优势在于:

  • 管理方便:角色可以包含多个权限,简化了权限管理的复杂度。
  • 灵活性高:可以根据需要动态调整用户的角色,进而控制其访问权限。

在实际项目中,通常会有一个角色和权限的对应关系表,角色下包含多个权限,用户可以被分配一个或多个角色。

希望这篇文章能对大家在权限管理的实践中有所帮助。如果有任何疑问或建议,欢迎在评论区留言讨论!

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

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

相关文章

CANoe的数据回放功能

文章目录 CANoe简介1.Offline回放功能2.Replay Block回放模块3.两者的异同 CANoe简介 CANoe&#xff08;CAN open environment&#xff09;&#xff1a; 用于汽车ECU网络仿真、数据分析、测试和诊断&#xff0c;还可以进行数据回放、程序刷写等。具有实时报文跟踪、数据解析及…

Android开发启动页跳过倒计时效果

Android开发启动页跳过倒计时效果 app启动页都会放些广告图&#xff0c;然后倒计时跳过。 一、思路&#xff1a; 不是很难&#xff0c;就用用个倒计时控制mHandler.sendEmptyMessageDelayed(WHAT_COUNT_DOWN, 100); 二、效果图&#xff1a; 三、关键代码&#xff1a; publ…

消息队列面试题——第二篇

1. rocketmq、rabbitmq、kafka的区别 架构设计和消息模型 特性rocketmqrabbitmqkafka消息模型基于主题和消费组&#xff0c;支持发布/订阅和点对点两种模型基于队列模型&#xff0c;支持发布/订阅和点对点两种模型基于分区的主题模型&#xff0c;主要用于日志流式处理和高吞吐…

基于SSM创城志愿者管理系统JAVA|VUE|Springboot计算机毕业设计源代码+数据库+LW文档+开题报告+答辩稿+部署教+代码讲解

源代码数据库LW文档&#xff08;1万字以上&#xff09;开题报告答辩稿 部署教程代码讲解代码时间修改教程 一、开发工具、运行环境、开发技术 开发工具 1、操作系统&#xff1a;Window操作系统 2、开发工具&#xff1a;IntelliJ IDEA或者Eclipse 3、数据库存储&#xff1a…

RNN心脏病预测

本文为为&#x1f517;365天深度学习训练营内部文章 原作者&#xff1a;K同学啊 一 前期准备 1.数据导入 import pandas as pd from keras.optimizers import Adam from matplotlib import pyplot as plt from sklearn.model_selection import train_test_split from sklearn.p…

jenkins 插件Publish Over SSH

一、安装插件 二、配置sshserver http://192.168.31.156:8080/manage/configure 三、添加自由风格&#xff1a;PublishOverSSHDemo 我们将工作目录&#xff1a;/var/lib/jenkins/workspace/PublishOverSSHDemo下的图片m3.jpeg 同步到目标143服务器目录&#xff1a;/root/imag…

Mysql(七) --- 索引

文章目录 前言1.简介1.1.索引是什么&#xff1f;1.2.为什么使用索引? 2.索引应该使用什么数据结构&#xff1f;2.1.Hash2.2.二叉搜索树2.3.N叉树2.4.B树2.4.1. 简介2.4.2. B树的特点2.4.3. B树和B树的对比 3.Mysql中的页3.1.为什么要使用页3.2.页文件头和页文件尾3.3.页主体3.…

Python开源项目月排行 2024年9月

#2024年9月2024年9月29日1jax一个开源的高性能数值计算库&#xff0c;旨在为机器学习和科学计算提供灵活性和效率。该项目由 Google 研发&#xff0c;并在 GitHub 上进行维护。AX 主要用于以下几个方面&#xff1a; 自动微分&#xff1a;提供高效的自动微分功能&#xff0c;支持…

嵌入式面试——FreeRTOS篇(九) 内存管理

本篇为&#xff1a;FreeRTOS 内存管理篇 一、FreeRTOS内存管理简介 1、FreeRTOS内存管理介绍 答&#xff1a; 在使用 FreeRTOS 创建任务、队列、信号量等对象的时&#xff0c;一般都提供了两种方法&#xff1a; 动态方法创建&#xff1a;自动地从 FreeRTOS 管理的内存堆中申…

【AI绘画教程】StableDiffusion出图颜色偏白发灰?用好VAE立马解决!(附VAE模型下载)

大家好&#xff0c;我是画画的小强 之前已经给大家推荐过不少AI绘画中 Stable Diffusion WebUI 的大模型&#xff0c;今天为大家介绍一下 WebUI 中“外挂VAE”的相关内容&#xff0c;可以解决我们在用大模型出图过程中出现的图像颜色发灰、发白的问题&#xff0c;一起来看看吧…

话说你们维保到期通知都是谁通知的

离谱了&#xff0c;公司有个客户维保到期了 过了2个月才发现。 白干了两个月&#xff0c; 客户也不愿意给这两个月钱。 现在商务和运维在扯皮&#xff0c; 商务说运维部门应该到期给客户发通知&#xff0c; 运维说商务到期要续签&#xff0c; 就应该商务去通知。 然后老…

ppt怎么做出高级感?找对高级ppt模板,轻松一键替换

想问问大家国庆节后的工作忙吗&#xff1f;小编的大厂朋友们都忙疯了&#xff01; 都在忙着做各种项目的执行总结PPT报告&#xff0c;和接下来的工作计划展望&#xff01;做出来的PPT还会被领导嫌弃排版没创意、不高级...... 这不&#xff0c;还来找小编&#xff0c;问有没有什…

水库抽样算法(大数据算法作业)

时隔一个多月&#xff0c;终于想起来写大数据算法基础的实验报告&#xff0c;主要是快截止了&#xff0c;hh 这两天加急把这个报告写完了~ 接下来&#xff0c;写一写证明过程&#xff08;参考书籍&#xff1a;高等教育出版社《数据科学与工程算法基础》&#xff09;主要代码以…

MODBUS协议介绍,通过MODBUS协议控制伺服电机工作

1.前言 modbus协议本身的介绍&#xff0c;请大家自行查阅资料。本文简单介绍一下如何通过MODBUS协议组装控制指令。 最近搞了一个项目&#xff0c;要驱动伺服电机工作。通过下位机STM32 407 100封脚 给伺服电机发控制指令。电机和下位机之前的通信采用RS485串口通信&#xff…

seaCMS v12.9代码审计学习(下半)

文章目录 admin/admin_safe.php任意文件下载CSRF 添加管理员账户CSRF配合XSS弹cookie admin/admin_safe.php任意文件下载 在admin_safe.php文件下有着这么一段代码&#xff0c;他的作用时检查action的值是否为download&#xff0c;如果为download那么将你传入的文件直接打印给…

LeetCode题练习与总结:二叉树的序列化与反序列化--297

一、题目描述 序列化是将一个数据结构或者对象转换为连续的比特位的操作&#xff0c;进而可以将转换后的数据存储在一个文件或者内存中&#xff0c;同时也可以通过网络传输到另一个计算机环境&#xff0c;采取相反方式重构得到原数据。 请设计一个算法来实现二叉树的序列化与…

校园网环境下基于OpenWRT的路由器选型与解决方案

校园网环境下基于OpenWRT的路由器选型与解决方案 网页认证(锐捷认证)解除校园网设备限制,路由器选型和解决方案 openwrt 我们学校校园网一个账号只能登录两台设备&#xff0c;多了直接就退出联网状态&#xff0c;然后校园网是基于锐捷认证进行认证的&#xff0c;然后通过ment…

基于逻辑回归实现乳腺癌预测

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

使用IDEA生成API文档

1. 在IDEA中&#xff0c;Tools->Generate JavaDoc Scope 2.Output Directory里面放&#xff0c;生成的目录。 Other command line arguments:-encoding utf-8 -charset utf-8&#xff08;解决乱码&#xff09; 3.点击ok&#xff0c;生成的效果图

构建数字文化产业链,拓展文化产业发展空间

在当今全球化和数字化的双重浪潮下&#xff0c;文化产业正以前所未有的速度进行变革和升级。作为文化与科技深度融合的产物&#xff0c;数字文化产业链正以其独特的魅力和无限的潜力&#xff0c;引领文化产业向更高层次、更广领域迈进。 数字文化产业链的构建&#xff0c;不仅…