基于springboot注解的shiro 授权及角色认证

目录

授权

后端接口服务注解

授权验证-没有角色无法访问

授权验证-获取角色进行验证 

授权验证-获取权限进行验证

授权验证-异常处理


授权

用户登录后,需要验证是否具有指定角色指定权限。Shiro也提供了方便的工具进行判 断。 这个工具就是Realm的doGetAuthorizationInfo方法进行判断。

触发权限判断的有两种 方式

(1) 在页面中通过shiro:****属性判断

(2) 在接口服务中通过注解@Requires****进行判断

后端接口服务注解

通过给接口服务方法添加注解可以实现权限校验,可以加在控制器方法上,也可以加 在业务方法上,一般加在控制器方法上。常用注解如下:

(1)@RequiresAuthentication

验证用户是否登录,等同于方法subject.isAuthenticated()

(2)@RequiresUser

验证用户是否被记忆: 登录认证成功subject.isAuthenticated()为true 登录后被记忆subject.isRemembered()为true

(3)@RequiresGuest

验证是否是一个guest的请求,是否是游客的请求 此时subject.getPrincipal()为null

(4)@RequiresRoles

验证subject是否有相应角色,有角色访问方法,没有则会抛出异常 AuthorizationException。 例如:

@RequiresRoles(“aRoleName”)

void someMethod();

只有subject有aRoleName角色才能访问方法someMethod()

(5)@RequiresPermissions

验证subject是否有相应权限,有权限访问方法,没有则会抛出异常 AuthorizationException。 例如:

@RequiresPermissions (“file:read”,”wite:aFile.txt”)

void someMethod();

subject必须同时含有file:read和wite:aFile.txt权限才能访问方法someMethod()

授权验证-没有角色无法访问

(1)添加 controller 方法,并添加验证角色注解 


//登录认证验证角色 
@RequiresRoles("admin") 
@GetMapping("userLoginRoles") 
@ResponseBody 
public String userLoginRoles() { 
 System.out.println("登录认证验证角色"); 
 return "验证角色成功"; 
}

(2)修改 main.html

<body> 
 <h1>Shiro 登录认证后主页面</h1> 
 <br> 
 登录用户为:<span th:text="${session.user}"></span> 
 <br> 
 <a href="/logout">登出</a> 
<br> 
 <a href="/myController/userLoginRoles">测试授权</a> 
</body>

(3)修改 MyRealm 方法

//自定义授权方法:获取当前登录用户权限信息,返回给 Shiro 用来进行授权对比 
@Override 
protected AuthorizationInfo 
doGetAuthorizationInfo(PrincipalCollection principalCollection) { 
 System.out.println("进入自定义授权方法"); 
 return null; 
} 

(4)运行测试

授权验证-获取角色进行验证 

(1)修改 MyRealm 方法 

//自定义授权方法:获取当前登录用户权限信息,返回给 Shiro 用来进行授权对比 
@Override 
protected AuthorizationInfo 
doGetAuthorizationInfo(PrincipalCollection principalCollection) { 
 System.out.println("进入自定义授权方法"); 
 //1 创建对象,存储当前登录的用户的权限和角色 
 SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); 
 //2 存储角色 
 info.addRole("admin"); 
 //返回 
 return info; 
} 

(2)运行测试

 (3)确认库表

CREATE TABLE `role` ( 
 `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '编号', 
 `name` VARCHAR(30) DEFAULT NULL COMMENT '角色名', 
 `desc` VARCHAR(50) DEFAULT NULL COMMENT '描述', 
 `realname` VARCHAR(20) DEFAULT NULL COMMENT '角色显示名', 
 PRIMARY KEY (`id`) 
) ENGINE=INNODB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='角色表'; 

CREATE TABLE `role_user` ( 
 `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '编号', 
 `uid` BIGINT(20) DEFAULT NULL COMMENT '用户 id', 
 `rid` BIGINT(20) DEFAULT NULL COMMENT '角色 id', 
 PRIMARY KEY (`id`) 
) ENGINE=INNODB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='角色用户映射表'; 

 (4)查询 sql 根据用户名查询对应角色信息

SELECT NAME FROM role WHERE id IN (SELECT rid FROM role_user WHERE uid=(SELECT id FROM USER WHERE NAME='张三'));

 (5)mapper 方法

@Repository 
public interface UserMapper extends BaseMapper<User> { 
 @Select("SELECT NAME FROM role WHERE id IN (SELECT rid FROM 
role_user WHERE uid=(SELECT id FROM USER WHERE NAME=#{principal}))") 
 List<String> getUserRoleInfoMapper(@Param("principal") String 
principal); 
}

(6)service 实现

//获取用户的角色信息 
@Override 
public List<String> getUserRoleInfo(String principal) { 
 return userMapper.getUserRoleInfoMapper(principal); 
} 

 (7)MyRealm 方法改造

//自定义授权方法:获取当前登录用户权限信息,返回给 Shiro 用来进行授权对比 
@Override 
protected AuthorizationInfo 
doGetAuthorizationInfo(PrincipalCollection principalCollection) { 
 System.out.println("进入自定义授权方法"); 
 //获取当前用户身份信息 
 String principal = 
principalCollection.getPrimaryPrincipal().toString(); 
 //调用接口方法获取用户的角色信息 
 List<String> roles = userService.getUserRoleInfo(principal); 
 System.out.println("当前用户角色信息:"+roles); 
 //创建对象,存储当前登录的用户的权限和角色 
 SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); 
 //存储角色 
 info.addRoles(roles); 
 //返回 
 return info; 
} 

(8)启动登录测试

授权验证-获取权限进行验证

获取权限验证和获取角色相类似

(1)确认库表

CREATE TABLE `permissions` ( 
 `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '编号', 
 `name` VARCHAR(30) DEFAULT NULL COMMENT '权限名', 
 `info` VARCHAR(30) DEFAULT NULL COMMENT '权限信息', 
 `desc` VARCHAR(50) DEFAULT NULL COMMENT '描述', 
 PRIMARY KEY (`id`) 
) ENGINE=INNODB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='权限表';

CREATE TABLE `role_ps` ( 
 `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '编号', 
 `rid` BIGINT(20) DEFAULT NULL COMMENT '角色 id', 
 `pid` BIGINT(20) DEFAULT NULL COMMENT '权限 id', 
 PRIMARY KEY (`id`) 
) ENGINE=INNODB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='角色权限映射表`

 

(2)查询 sql 根据角色名查询对应权限信息

SELECT info FROM permissions WHERE id IN (SELECT pid FROM role_ps WHERE rid IN (SELECT id FROM role WHERE NAME IN('admin','userMag')));

(3)mapper 方法

@Select({ 
 "<script>", 
 "select info FROM permissions WHERE id IN ", 
 "(SELECT pid FROM role_ps WHERE rid IN (", 
 "SELECT id FROM role WHERE NAME IN ", 
 "<foreach collection='roles' item='name' open='(' 
separator=',' close=')'>", 
 "#{name}", 
 "</foreach>", 
 "))", 
 "</script>" 
}) 
List<String> getUserPermissionInfoMapper(@Param("roles")List<String> 
roles);

 (4)service 实现

//获取用户角色的权限信息 
@Override 
public List<String> getUserPermissionInfo(List<String> roles) { 
 return userMapper.getUserPermissionInfoMapper(roles); 
}

(5)MyRealm 方法改造

//自定义授权方法:获取当前登录用户权限信息,返回给 Shiro 用来进行授权对比 
@Override 
protected AuthorizationInfo 
doGetAuthorizationInfo(PrincipalCollection principalCollection) { 
 System.out.println("进入自定义授权方法"); 
 //获取当前用户身份信息 
 String principal = 
principalCollection.getPrimaryPrincipal().toString(); 
 //调用接口方法获取用户的角色信息 
 List<String> roles = userService.getUserRoleInfo(principal); 
 System.out.println("当前用户角色信息:"+roles); 
 //调用接口方法获取用户角色的权限信息 
 List<String> permissions = 

userService.getUserPermissionInfo(roles); 
 System.out.println("当前用户权限信息:"+permissions); 
 //创建对象,存储当前登录的用户的权限和角色 
 SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); 
 //存储角色 
 info.addRoles(roles); 
 //存储权限信息 
 info.addStringPermissions(permissions); 
 //返回 
 return info; 
}

(6)添加 controller 方法

//登录认证验证权限 
@RequiresPermissions("user:delete") 
@GetMapping("userPermissions") 
@ResponseBody 
public String userLoginPermissions() { 
 System.out.println("登录认证验证权限"); 
 return "验证权限成功"; 
}

(7)改造 main.html

<body> 
 <h1>Shiro 登录认证后主页面</h1> 
 <br> 
 登录用户为:<span th:text="${session.user}"></span> 
 <br> 
 <a href="/logout">登出</a> 
 <br> 
 <a href="/myController/userLoginRoles">测试授权-角色验证</a> 
 <br> 
 <a href="/myController/userPermissions">测试授权-权限验证</a> 
</body> 

 (8)启动登录测试

授权验证-异常处理

(1)创建认证异常处理类,使用@ControllerAdvice 加@ExceptionHandler 实现特殊异 常处理。

@ControllerAdvice 
public class PermissionsException { 
 @ResponseBody 
 @ExceptionHandler(UnauthorizedException.class) 
 public String unauthorizedException(Exception ex){ 
 return "无权限"; 
 } 
 
 @ResponseBody 
 @ExceptionHandler(AuthorizationException.class) 
 public String authorizationException(Exception ex){ 
 return "权限认证失败"; 
 } 

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

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

相关文章

1.矢量引入

目录 一.什么是矢量 1.1 定义 1.2 公理与体系 1.3 矢量几何化 二.矢量间的相互作用 1.点积 2.点积应用 3.叉积 4. 叉积应用 三.矢量除法 1.单用叉积无法唯一定义矢量除法 2.矢量除法 四.复杂相互作用 1.混合积 2.双叉积 3.Laplace公式 五.泛函的广义矢量理论…

hive任务reduce步骤卡在99%原因及解决

我们在写sql的时候经常发现读取数据不多&#xff0c;但是代码运行时间异常长的情况&#xff0c;这通常是发生了数据倾斜现象。数据倾斜现象本质上是因为数据中的key分布不均匀&#xff0c;大量的数据集中到了一台或者几台机器上计算&#xff0c;这些数据的计算速度远远低于平均…

NVM-Nodejs多版本管理工具

NVM:&#x1f50e;:下载点我 下载含有 setup.exe的 下载完成之后修改一下settings.txt 文件&#xff0c;在原有的基础上直接加入这些配置 root: D:\nvm path: D:\nvm\nodejs node_mirror: https://npm.taobao.org/mirrors/node/ npm_mirror: https://npm.taobao.org/mirrors…

旅游有哪些好玩的地方? 今天用python分析适合年轻人的旅游攻略

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 “旅”是旅行&#xff0c;外出&#xff0c;即为了实现某一目的而在空间上从甲地到乙地的行进过程&#xff1b; “游”是外出游览、观光、娱乐&#xff0c;即为达到这些目的所作的旅行。 二者合起来即旅游。所以&#…

JavaScript 基础 DOM (四)

正则表达式正则表达式 正则基本使用 定义规则 const reg /表达式/其中/ /是正则表达式字面量正则表达式也是对象 使用正则 test()方法 用来查看正则表达式与指定的字符串是否匹配 如果正则表达式与指定的字符串匹配 &#xff0c;返回true&#xff0c;否则false reg.test(…

【算法】【算法杂谈】旋转数组的二分法查找

目录 前言问题介绍解决方案代码编写java语言版本c语言版本c语言版本 思考感悟写在最后 前言 当前所有算法都使用测试用例运行过&#xff0c;但是不保证100%的测试用例&#xff0c;如果存在问题务必联系批评指正~ 在此感谢左大神让我对算法有了新的感悟认识&#xff01; 问题介…

1722_PolySpace Bug Finder的几种启动方式

全部学习汇总&#xff1a; GreyZhang/g_matlab: MATLAB once used to be my daily tool. After many years when I go back and read my old learning notes I felt maybe I still need it in the future. So, start this repo to keep some of my old learning notes servral …

pinia

一、pinia是什么&#xff1f; &#x1f69c;&#x1f69c;&#x1f69c;Pinia是最接近西班牙语中的菠萝的词&#xff1b;背景&#xff1a;大概2019年&#xff0c;是作为一个实验为Vue重新设计状态管理&#xff0c;让它用起来像组合式API。从那时到现在&#xff0c;最初的设计原…

Vulkan Tutorial 5 顶点缓冲区

目录 16 顶点缓冲区 顶点着色器 顶点数据 管道顶点输入 17 顶点缓冲区创建 缓冲区创建 内存要求 内存分配 填充顶点缓冲区 18 暂存缓冲区 传输队列 使用暂存缓冲区 19 索引缓冲区 索引缓冲区创建 使用索引缓冲区 16 顶点缓冲区 我们将用内存中的顶点缓冲区替换…

5。STM32裸机开发(4)

嵌入式软件开发学习过程记录&#xff0c;本部分结合本人的学习经验撰写&#xff0c;系统描述各类基础例程的程序撰写逻辑。构建裸机开发的思维&#xff0c;为RTOS做铺垫&#xff08;本部分基于库函数版实现&#xff09;&#xff0c;如有不足之处&#xff0c;敬请批评指正。 &…

拥抱 Spring 全新 OAuth 解决方案

以下全文 Spring Authorization Server 简称为: SAS 背景 Spring 团队正式宣布 Spring Security OAuth 停止维护&#xff0c;该项目将不会再进行任何的迭代 目前 Spring 生态中的 OAuth2 授权服务器是 Spring Authorization Server 已经可以正式生产使用 作为 SpringBoot 3.0…

FastThreadLocal 原理解析

FastThreadLocal 每个 FastThread 包含一个 FastThreadLocalMap&#xff0c;每个 FastThreadLocalThread 中的多个 FastThreadLocal 占用不同的索引。每个 InternalThreadLocalMap 的第一个元素保存了所有的 ThreadLocal 对象。之后的元素保存了每个 ThreadLocal 对应的 value …

SpringBoot 之 Tomcat 与 Undertow 容器性能对比

一、前言&#x1f525; 环境说明&#xff1a;Windows10 Idea2021.3.2 Jdk1.8 SpringBoot 2.3.1.RELEASE 在上一篇《SpringBoot 之配置 Undertow 容器》一文中写道&#xff1a;“Undertow 的性能和内存使用方面都要优于 Tomcat 容器”, 这一期&#xff0c;我就要给大家来求证…

批处理文件(.bat)启动redis及任何软件(同理)

批处理文件 每次从文件根目录用配置文件格式来启动redis太麻烦了 可以在桌面上使用批处理文件&#xff08;.bat&#xff09;启动Redis&#xff0c;请按照以下步骤进行操作&#xff1a; 打开文本编辑器&#xff0c;如记事本。 在编辑器中输入以下内容&#xff1a; 将文件保存…

【JavaSE】Java基础语法(三十六):File IO流

文章目录 1. File1.1 File类概述和构造方法1.2 绝对路径和相对路径1.3 File 类的常用方法1.4 递归删除文件夹及其下面的文件 2. IO2.1 分类2.2 字节输出流2.3 字节输入流2.4 文件的拷贝2.5 文件拷贝效率优化2.6 释放资源2.7 缓冲流2.8 编码表 3. commons-io 工具包3.1 API 1. F…

gitlab搭建与认证登录

gitlab搭建与认证登录 gitlab的安装配置gitlab中Ldap认证配置 gitlab的安装配置 参考链接&#xff1a; Gitlab 仓库搭建&#xff08;详细版&#xff09; 以下4项注意点&#xff1a; gitlab安装包&#xff0c;直接访问在浏览器上下载速度很慢&#xff0c;可复制链接到迅雷中进…

怎样用一周时间研究 ChatGPT

我是怎样用一周时间研究 ChatGPT 的&#xff1f; 上周大概开了 20 多个会&#xff0c;其中有一些是见了觉得今年可能会比较活跃出手的机构&#xff0c;其余见的绝大多数是和 ChatGPT 相关。 我后面就以 ChatGPT 为例&#xff0c;讲下我是如何快速一周 cover 一个赛道的&#x…

机器视觉怎么对陶瓷板的外观尺寸进行自动检测?

随着工业自动化的不断发展&#xff0c;机器视觉技术在制造业中的应用越来越广泛。在陶瓷板行业中&#xff0c;机器视觉技术可以用于自动检测陶瓷板的外观尺寸&#xff0c;提高生产效率和产品质量。下面我们来介绍机器视觉如何对陶瓷板的外观尺寸进行自动检测。 一、检测原理 …

vue常用指令

vue是前端框架&#xff0c;使用vue指令时需要导入vue.js文件&#xff1b;vue的常用指令有以下这些&#xff1a; v-bind、v-model&#xff1a;双向绑定数据、链接 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8">&…

SAP-MM-采购申请字段解析

采购申请抬头以及行项目字段解析 1、采购申请类型&#xff1a; 对PR进行分类&#xff1b; 控制PR行项目的编号间隔&#xff1b; 控制PR编号范围&#xff0c;以及是否内/外部给号&#xff1b; 控制PR的屏幕选择格式&#xff1b; 控制PR是否允许凭证抬头审批&#xff0c;如果允…