MySQL中authorization_Shiro系列之Shiro+Mysql实现用户受权(Authorization)_mysql

2024-03-04 08:50

本文主要是介绍MySQL中authorization_Shiro系列之Shiro+Mysql实现用户受权(Authorization)_mysql,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Shiro系列之Shiro+mysql实现用户授权(Authorization)

昨天,我在《Shiro系列之Shiro+Mysql实现用户认证(Authentication)》中简单介绍了使用Shiro+Mysql实现用户认证的功能,今天我们继续使用其中的示例,讲解一下如何实现用户授权。

所谓授权,就是判断当前用户具体哪些权限,能够执行哪些操作,或是访问哪些资源(Web中的URL,又或是页面上的一个按钮,一个编辑框等都可以视为资源)。因此我们需要数据表来存储这些资源信息,以及用户、角色和资源的分配关系。

上文中已经创建了用户表,在本文中我们需要再创始角色表、资源表,以及用户和角色、角色和资源之间的关系表。这里仅为了需要让测试程序跑通,所以字段都很简单,在使用中可根据实际情况对字段进行增加。

CREATE TABLE `sec_role` ( `role_id` int(10) unsigned NOT NULL AUTO_INCREMENT, `role_name` varchar(64) COLLATE utf8_bin DEFAULT NULL, `created_time` datetime DEFAULT NULL, `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`role_id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

CREATE TABLE `sec_permission` ( `permission_id` int(10) unsigned NOT NULL AUTO_INCREMENT, `permission_name` varchar(64) COLLATE utf8_bin DEFAULT NULL, `created_time` datetime DEFAULT NULL, `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`permission_id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

CREATE TABLE `sec_user_role` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `user_id` int(10) unsigned DEFAULT NULL, `role_id` int(10) unsigned DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

CREATE TABLE `sec_role_permission` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `permission_id` int(10) unsigned NOT NULL, `role_id` int(10) unsigned DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

建好表之后,我们就需要为JdbcRealm对象指定用户、角色和权限的查询语句。在Shiro的配置文件中添加如下代码:

[main] dataSource=org.springframework.jdbc.datasource.DriverManagerDataSource dataSource.driverClassName=com.mysql.jdbc.Driver dataSource.url=jdbc:mysql://127.0.0.1:3306/etao_java dataSource.username=root dataSource.password=cope9020 jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm jdbcRealm.permissionsLookupEnabled = true jdbcRealm.dataSource=$dataSource #用户认证(登录)查询语句,以用户名为查询条件 jdbcRealm.authenticationQuery = SELECT password FROM sec_user WHERE user_name = ? #用户角色查询语句,以用户名为查询条件,判断用户是否拥有某个角色 jdbcRealm.userRolesQuery = SELECT role_name from sec_user_role left join sec_role using(role_id) left join sec_user using(user_id) WHERE user_name = ? #资源许可查询语句,以角色名称为查询条件,判断角色是否拥有某个资源的许可 jdbcRealm.permissionsQuery = SELECT permission_name FROM sec_role_permission left join sec_role using(role_id) left join sec_permission using(permission_id) WHERE role_name = ?

关于这三条查询语句,在这里多说两句,小伙伴们不要嫌我啰嗦。

用户认证的查询语句中,只需要以用户名为查询条件,查询出密码字段即可,如果您在select后面使用了星号(*)或是查询字段多于一个,都无法通过用户认证。

用户角色查询语句,以用户名为查询条件,通过多表关联,查询出角色名字段即可,不可使用星号,或多个字段

资源许可查询语句,以角色名为查询条件,通过多表关联,查询出资源名称字段即可,不可使用星号,或多个字段

配置文件修改好之后,就可以编写测试代码了。

public class JdbcRealmTest { @Test public void test() { // 1.获取SecurityManager工厂,此处使用ini配置文件初始化SecurityManager Factory factory = new IniSecurityManagerFactory("classpath:shiro-jdbc-realm.ini"); // 2.获取SecurityManager实例,并绑定到SecurityUtils SecurityManager sm = factory.getInstance(); SecurityUtils.setSecurityManager(sm); // 3.得到Subject Subject subject = SecurityUtils.getSubject(); // 4.创建用户登录凭证 UsernamePasswordToken token = new UsernamePasswordToken("chris.mao@emerson.com", "chrismao"); token.setRememberMe(true); // 5.登录,如果登录失败会抛出不同的异常,根据异常输出失败原因 try { subject.login(token); // 6.判断是否成功登录 assertEquals(true, subject.isAuthenticated()); System.out.println("登录成功!!"); // 判断用户是否拥有某个角色 assertEquals(true, subject.hasRole("admin")); // 使用Shiro自带的断言判断用户是否有被授权 subject.checkRole("manager"); subject.checkPermission("create_user1"); // 7.注销用户 subject.logout(); } catch (IncorrectCredentialsException e) { System.out.println("登录密码错误. Password for account " + token.getPrincipal() + " was incorrect."); } catch (ExcessiveAttemptsException e) { System.out.println("登录失败次数过多"); } catch (LockedAccountException e) { System.out.println("帐号已被锁定. The account for username " + token.getPrincipal() + " was locked."); } catch (DisabledAccountException e) { System.out.println("帐号已被禁用. The account for username " + token.getPrincipal() + " was disabled."); } catch (ExpiredCredentialsException e) { System.out.println("帐号已过期. the account for username " + token.getPrincipal() + " was expired."); } catch (UnknownAccountException e) { System.out.println("帐号不存在. There is no user with username of " + token.getPrincipal()); } catch (UnauthorizedException e) { System.out.println("您没有得到相应的授权!" + e.getMessage()); } } }

这里使用了Shiro自带的断言,用于判断用户是否有被授权,如果没关被授权,会抛出UnauthorizedException异常,小伙伴们可以捕捉此异常进行相应的处理。

版权声明:本文为博主原创文章,未经博主允许不得转载。

欢迎大家阅读《Shiro系列之Shiro+Mysql实现用户受权(Authorization)_mysql》,跪求各位点评,by 搞代码

e7ce419cf2d6ad34d01da2ceb8829eed.png

微信 赏一包辣条吧~

023a57327877fb4402bcc76911ec18ea.png

支付宝 赏一听可乐吧~

这篇关于MySQL中authorization_Shiro系列之Shiro+Mysql实现用户受权(Authorization)_mysql的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/772658

相关文章

MySQL中On duplicate key update的实现示例

《MySQL中Onduplicatekeyupdate的实现示例》ONDUPLICATEKEYUPDATE是一种MySQL的语法,它在插入新数据时,如果遇到唯一键冲突,则会执行更新操作,而不是抛... 目录1/ ON DUPLICATE KEY UPDATE的简介2/ ON DUPLICATE KEY UP

Python中Json和其他类型相互转换的实现示例

《Python中Json和其他类型相互转换的实现示例》本文介绍了在Python中使用json模块实现json数据与dict、object之间的高效转换,包括loads(),load(),dumps()... 项目中经常会用到json格式转为object对象、dict字典格式等。在此做个记录,方便后续用到该方

MySQL分库分表的实践示例

《MySQL分库分表的实践示例》MySQL分库分表适用于数据量大或并发压力高的场景,核心技术包括水平/垂直分片和分库,需应对分布式事务、跨库查询等挑战,通过中间件和解决方案实现,最佳实践为合理策略、备... 目录一、分库分表的触发条件1.1 数据量阈值1.2 并发压力二、分库分表的核心技术模块2.1 水平分

JWT + 拦截器实现无状态登录系统

《JWT+拦截器实现无状态登录系统》JWT(JSONWebToken)提供了一种无状态的解决方案:用户登录后,服务器返回一个Token,后续请求携带该Token即可完成身份验证,无需服务器存储会话... 目录✅ 引言 一、JWT 是什么? 二、技术选型 三、项目结构 四、核心代码实现4.1 添加依赖(pom

SpringBoot路径映射配置的实现步骤

《SpringBoot路径映射配置的实现步骤》本文介绍了如何在SpringBoot项目中配置路径映射,使得除static目录外的资源可被访问,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一... 目录SpringBoot路径映射补:springboot 配置虚拟路径映射 @RequestMapp

Python与MySQL实现数据库实时同步的详细步骤

《Python与MySQL实现数据库实时同步的详细步骤》在日常开发中,数据同步是一项常见的需求,本篇文章将使用Python和MySQL来实现数据库实时同步,我们将围绕数据变更捕获、数据处理和数据写入这... 目录前言摘要概述:数据同步方案1. 基本思路2. mysql Binlog 简介实现步骤与代码示例1

Redis实现高效内存管理的示例代码

《Redis实现高效内存管理的示例代码》Redis内存管理是其核心功能之一,为了高效地利用内存,Redis采用了多种技术和策略,如优化的数据结构、内存分配策略、内存回收、数据压缩等,下面就来详细的介绍... 目录1. 内存分配策略jemalloc 的使用2. 数据压缩和编码ziplist示例代码3. 优化的

基于C#实现PDF转图片的详细教程

《基于C#实现PDF转图片的详细教程》在数字化办公场景中,PDF文件的可视化处理需求日益增长,本文将围绕Spire.PDFfor.NET这一工具,详解如何通过C#将PDF转换为JPG、PNG等主流图片... 目录引言一、组件部署二、快速入门:PDF 转图片的核心 C# 代码三、分辨率设置 - 清晰度的决定因

Java Kafka消费者实现过程

《JavaKafka消费者实现过程》Kafka消费者通过KafkaConsumer类实现,核心机制包括偏移量管理、消费者组协调、批量拉取消息及多线程处理,手动提交offset确保数据可靠性,自动提交... 目录基础KafkaConsumer类分析关键代码与核心算法2.1 订阅与分区分配2.2 拉取消息2.3

SpringBoot集成XXL-JOB实现任务管理全流程

《SpringBoot集成XXL-JOB实现任务管理全流程》XXL-JOB是一款轻量级分布式任务调度平台,功能丰富、界面简洁、易于扩展,本文介绍如何通过SpringBoot项目,使用RestTempl... 目录一、前言二、项目结构简述三、Maven 依赖四、Controller 代码详解五、Service