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

相关文章

Python实现对阿里云OSS对象存储的操作详解

《Python实现对阿里云OSS对象存储的操作详解》这篇文章主要为大家详细介绍了Python实现对阿里云OSS对象存储的操作相关知识,包括连接,上传,下载,列举等功能,感兴趣的小伙伴可以了解下... 目录一、直接使用代码二、详细使用1. 环境准备2. 初始化配置3. bucket配置创建4. 文件上传到os

MySQL查询JSON数组字段包含特定字符串的方法

《MySQL查询JSON数组字段包含特定字符串的方法》在MySQL数据库中,当某个字段存储的是JSON数组,需要查询数组中包含特定字符串的记录时传统的LIKE语句无法直接使用,下面小编就为大家介绍两种... 目录问题背景解决方案对比1. 精确匹配方案(推荐)2. 模糊匹配方案参数化查询示例使用场景建议性能优

关于集合与数组转换实现方法

《关于集合与数组转换实现方法》:本文主要介绍关于集合与数组转换实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Arrays.asList()1.1、方法作用1.2、内部实现1.3、修改元素的影响1.4、注意事项2、list.toArray()2.1、方

使用Python实现可恢复式多线程下载器

《使用Python实现可恢复式多线程下载器》在数字时代,大文件下载已成为日常操作,本文将手把手教你用Python打造专业级下载器,实现断点续传,多线程加速,速度限制等功能,感兴趣的小伙伴可以了解下... 目录一、智能续传:从崩溃边缘抢救进度二、多线程加速:榨干网络带宽三、速度控制:做网络的好邻居四、终端交互

mysql表操作与查询功能详解

《mysql表操作与查询功能详解》本文系统讲解MySQL表操作与查询,涵盖创建、修改、复制表语法,基本查询结构及WHERE、GROUPBY等子句,本文结合实例代码给大家介绍的非常详细,感兴趣的朋友跟随... 目录01.表的操作1.1表操作概览1.2创建表1.3修改表1.4复制表02.基本查询操作2.1 SE

MySQL中的锁机制详解之全局锁,表级锁,行级锁

《MySQL中的锁机制详解之全局锁,表级锁,行级锁》MySQL锁机制通过全局、表级、行级锁控制并发,保障数据一致性与隔离性,全局锁适用于全库备份,表级锁适合读多写少场景,行级锁(InnoDB)实现高并... 目录一、锁机制基础:从并发问题到锁分类1.1 并发访问的三大问题1.2 锁的核心作用1.3 锁粒度分

MySQL数据库中ENUM的用法是什么详解

《MySQL数据库中ENUM的用法是什么详解》ENUM是一个字符串对象,用于指定一组预定义的值,并可在创建表时使用,下面:本文主要介绍MySQL数据库中ENUM的用法是什么的相关资料,文中通过代码... 目录mysql 中 ENUM 的用法一、ENUM 的定义与语法二、ENUM 的特点三、ENUM 的用法1

MySQL count()聚合函数详解

《MySQLcount()聚合函数详解》MySQL中的COUNT()函数,它是SQL中最常用的聚合函数之一,用于计算表中符合特定条件的行数,本文给大家介绍MySQLcount()聚合函数,感兴趣的朋... 目录核心功能语法形式重要特性与行为如何选择使用哪种形式?总结深入剖析一下 mysql 中的 COUNT

java实现docker镜像上传到harbor仓库的方式

《java实现docker镜像上传到harbor仓库的方式》:本文主要介绍java实现docker镜像上传到harbor仓库的方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录1. 前 言2. 编写工具类2.1 引入依赖包2.2 使用当前服务器的docker环境推送镜像2.2

C++20管道运算符的实现示例

《C++20管道运算符的实现示例》本文简要介绍C++20管道运算符的使用与实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录标准库的管道运算符使用自己实现类似的管道运算符我们不打算介绍太多,因为它实际属于c++20最为重要的