当前位置: 首页 > news >正文

Spring Boot学习篇(十三)

Spring Boot学习篇(十三)

shiro安全框架使用篇(五)

1 准备工作

1.1 在SysUserMapper.xml中书写自定义标签

<select id="findRoles" resultType="string">select name from sys_role where id = (select roleid from sys_user_role where userid = (SELECT id FROM `sys_user` where username = #{username}))
</select>
<select id="findPerms" resultType="string">select name from sys_permission where id in(select perid from sys_role_permission where roleid in(select roleid from sys_user_role where userid in(SELECT id FROM `sys_user` where username =#{username})))
</select>

1.2 SysUserMapper接口书写自定义标签所对应的方法

//根据用户名查询角色
List<String> findRoles(String username);
//根据用户名查询权限
List<String> findPerms(String username);

1.3 login.html界面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h2 th:if="${msg!=null}" th:text="${msg}"></h2><form action="/users/login" method="post"><!--需要与控制器保持一致-->用户名:<input type="text" name="yhm">密码:<input type="password" name="mm">记住我: <input type="checkbox" name="jzw"><button>登录</button></form>
</body>
</html>

1.4 index.html界面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>主页<a href="/zhuxiao">注销</a><a href="/songs/find">查询商品</a><a href="/songs/update">更改商品</a><a href="/songs/insert">添加商品</a><a href="/songs/delete">删除商品</a>
</body>
</html>

1.5 qx.html界面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h1>你没有该访问权限</h1><a href="/index.html">点击进入主页</a>
</body>
</html>

1.6 SongsController类

package com.zlz.controller;import com.zlz.entity.Songs;
import com.zlz.service.ISongsService;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.authz.annotation.RequiresUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ResponseBody;import java.util.List;/*** <p>*  前端控制器* </p>** @author zlz* @since 2023-02-04*/
//跨域的问题  1.协议不同 2.地址不同 3.端口不同 三者满足其一,就是跨域
//(origins = "*") origins仅允许指定域名访问 (origins = "http://127.0.0.1:8848")
@CrossOrigin
@Controller
@RequestMapping("/songs")
public class SongsController {@AutowiredISongsService iSongsService;@RequestMapping("select")@ResponseBodypublic List<Songs> s(){return iSongsService.list();}@RequestMapping("find")public String a(){System.out.println("查询数据");return "index";}@RequestMapping("delete")////角色,需要自定义异常@RequiresRoles(value = {"经理","组长"},logical = Logical.OR)//判断是否具有权限的
//   @RequiresPermissions()public String b(){System.out.println("删除数据");return "index";}@RequiresUser@RequestMapping("update")public String c(){System.out.println("修改数据");return "index";}@RequestMapping("insert")public String d(){System.out.println("添加数据");return "index";}}

2.操作授权(全满足)

2.1 在MySqlRealm类里面(继承了AuthorizingRealm抽象类)书写授权方法的内容

@Resource
SysUserMapper sysUserMapper;
//授权方法
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection p) {//注意看方法的返回值,一般是返回方法返回值类型所对应的实现类(Simple开头+方法返回值类型)//①得到当前登录的用户名String yhm =(String)p.getPrimaryPrincipal();//②查询到该用户的角色和权限List<String> roles = sysUserMapper.findRoles(yhm);List<String> perms = sysUserMapper.findPerms(yhm);//③ 控制台打印 方便查看效果System.out.println(yhm+"具有权限"+roles);System.out.println(yhm+"具有角色"+perms);//④授权并返回SimpleAuthorizationInfo sm=new SimpleAuthorizationInfo();sm.addRoles(roles);sm.addStringPermissions(perms);return sm;
}

2.2 在ShiroConfig类的factoryBean方法中配置控制器过滤

//默认是roles[角色名1,角色名2...角色名n],因为底层用的是hasAllRoles方法,因此是必须含有全部权限
//下面代码表示经理和组长的权限都要满足才可以进行删除
map.put("/songs/delete","user,roles[经理,组长]");

2.3 在ShiroConfig类中的factoryBean方法配置没有权限时的跳转地址

//检测到没有权限时的地址
sb.setUnauthorizedUrl("/qx.html");

2.4 设置没有权限时跳转的页面(templates目录下)

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h1>你没有该访问权限</h1><a href="/index.html">点击进入主页</a>
</body>
</html>

2.5 测试

2.5.1 使用admin用户(具有经理权限)登录后并点击删除商品进入如下界面

在这里插入图片描述

2.5.2 使用aaa用户(具有组长权限)登录后并点击删除商品进入如下界面

在这里插入图片描述

3.操作授权(满足其中之一)

3.1 自定义角色过滤器类MyRolesFilter(继承RolesAuthorizationFilter类)

package com.zlz.filter;import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.CollectionUtils;
import org.apache.shiro.web.filter.authz.RolesAuthorizationFilter;import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
import java.util.Set;/*** 自定义角色过滤器*/
public class MyRolesFilter extends RolesAuthorizationFilter {@Overridepublic boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {Subject subject = this.getSubject(request, response);String[] rolesArray = (String[])mappedValue;if (rolesArray != null && rolesArray.length != 0) {Set<String> roles = CollectionUtils.asSet(rolesArray);boolean b=false;for (String role : roles) {//满足其中之一就返回,hasRole满足条件就为true,if(subject.hasRole(role)){b=true;break;}}return b;} else {return true;}}
}

3.2 核心代码(在ShiroConfig类中factoryBean方法中)

/**
* 自定义过滤器 换个名字好点 sb是ShiroFilterFactoryBean类型的对象
*/
Map<String, Filter> myFilter=new HashMap<>();
myFilter.put("myroles",new MyRolesFilter());
sb.setFilters(myFilter);
//设置删除商品需要经理或者组长其一的权限
map.put("/songs/delete","user,myroles[经理,组长]");

3.3 完整的ShiroConfig类代码

package com.zlz.config;import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import com.zlz.filter.MyRolesFilter;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.authc.LogoutFilter;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.crazycake.shiro.RedisCacheManager;
import org.crazycake.shiro.RedisManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;@Configuration
public class ShiroConfig {//shiro标签库@Beanpublic ShiroDialect sd(){return new ShiroDialect();}//配置安全管理器 shiro核心配置类@Beanpublic DefaultWebSecurityManager securityManager(){DefaultWebSecurityManager dms=new DefaultWebSecurityManager();//设置域(查询数据库dao类) 查哪里的数据库设置dms.setRealm(realm());//设置会话管理器dms.setSessionManager(new DefaultWebSessionManager());//设置记住我管理器dms.setRememberMeManager(ck());return dms;}@Beanpublic Realm realm(){MysqlRealm r=new MysqlRealm();//设置密码加密 登录是加密比对HashedCredentialsMatcher hsm = new HashedCredentialsMatcher();hsm.setHashAlgorithmName("sha-256");hsm.setHashIterations(100);r.setCredentialsMatcher(hsm);return r;}//shiro过滤器(核心)@Bean("shiroFilterFactoryBean")public ShiroFilterFactoryBean factoryBean(){ShiroFilterFactoryBean sb=new ShiroFilterFactoryBean();//设置安全管理器sb.setSecurityManager(securityManager());/*基本设置*///检测到没有登录的地址sb.setLoginUrl("/login.html");//检测到没有权限时的地址(这里是一种设置没有权限时候跳转的地址)sb.setUnauthorizedUrl("/qx.html");/*** 自定义过滤器 换个名字好点 sb是ShiroFilterFactoryBean类型的对象是通过map集合设置进去的*/Map<String, Filter> myFilter=new HashMap<>();myFilter.put("myroles",new MyRolesFilter());sb.setFilters(myFilter);//控制器过滤设置 拦截有顺序///*** anon 允许匿名访问  无需登录* user 需要登录后才能访问* roles 需要具有所有的角色* perms 需要具有所有的权限* logout 注销过滤器* authc 不包含记住我 需要登录*/Map<String,String> map=new LinkedHashMap<>();map.put("/*.html", "anon");//注销流程 自己清空sessionmap.put("/zhuxiao", "logout");map.put("/songs/find","anon");//myroles就是和之前定义的key值保持一致map.put("/songs/delete","user,myroles[经理,组长]");//放行写上面 拦截写下面sb.setFilterChainDefinitionMap (map);return sb;}@Beanpublic CookieRememberMeManager ck(){CookieRememberMeManager c=new CookieRememberMeManager();SimpleCookie sc=new SimpleCookie();sc.setHttpOnly(true);//防止js读取cookiesc.setMaxAge(60);//设置cookie时长sc.setName("zlz");c.setCookie(sc);return c;}
}

3.3 测试

3.3.1 组长权限(用户名为aaa)
a 点击删除按钮后跳转的界面

在这里插入图片描述

b 点击删除按钮后的idea控制台界面

在这里插入图片描述

3.3.2 管理员权限(用户名为admin)
a 点击删除按钮后跳转的界面

在这里插入图片描述

b 点击删除按钮后的idea控制台界面

在这里插入图片描述

4 设置注销后跳转的地址

4.1 核心代码

//Map<String, Filter> myFilter=new HashMap<>();
LogoutFilter logoutFilter = new LogoutFilter();
logoutFilter.setRedirectUrl("/index.html");//修改注销后的跳转地址,如果没有设置默认跳转的是login.html界面myFilter.put("logout",logoutFilter);

4.2 运行截图

在这里插入图片描述

相关文章:

Spring Boot学习篇(十三)

Spring Boot学习篇(十三) shiro安全框架使用篇(五) 1 准备工作 1.1 在SysUserMapper.xml中书写自定义标签 <select id"findRoles" resultType"string">select name from sys_role where id (select roleid from sys_user_role where userid (S…...

微软Bing的AI人工只能对话体验名额申请教程

微软Bing 免费体验名额申请教程流程ChatGPT这东西可太过火了。国外国内&#xff0c;圈里圈外都是人声鼎沸。微软&#xff0c;谷歌&#xff0c;百度这些大佬纷纷出手。连看个同花顺都有GPT概念了&#xff0c;搞技术&#xff0c;做生意的看来都盯上了 流程 下面就讲一下如何申…...

怎么打造WhatsApp Team?SaleSmartly(ss客服)告诉你

关键词&#xff1a;WhatsApp Team SaleSmartly&#xff08;ss客服&#xff09; 您是否正在寻找一种让您的团队能够在 WhatsApp协作消息传递的解决方案?拥有了 WhatsApp Team&#xff0c;不仅效率提升&#xff0c;还可以在智能聊天工具中比如SaleSmartly&#xff08;ss客服&…...

IPV4地址的原理和配置

第三章&#xff1a;IP地址的配置 IPv4&#xff08;Internet Protocol Version 4&#xff09;协议族是TCP/IP协议族中最为核心的协议族。它工作在TCP/IP协议栈的网络层&#xff0c;该层与OSI参考模型的网络层相对应。网络层提供了无连接数据传输服务&#xff0c;即网络在发送分…...

软件测试面试准备——(一)Selenium(1)基础问题及自动化测试

滴滴面试&#xff1a;1. 自己负责哪部分功能&#xff1f;农餐对接系统分为了两大子系统&#xff0c;一个是个人订餐系统&#xff0c;二是餐馆、个人与农产品供应商进行农产品交易系统。我主要负责组织测试人员对该系统进行测试。我们测试分为两个阶段&#xff1a;一、功能测试阶…...

AcWing 1230.K倍区间

AcWing 1230. K倍区间 题目描述 给定一个长度为 NNN 的数列&#xff0c;A1,A2,…ANA_1, A_2, … A_NA1​,A2​,…AN​ &#xff0c;如果其中一段连续的子序列 Ai,Ai1,…AjA_i, A_{i1}, … A_jAi​,Ai1​,…Aj​ 之和是 KKK 的倍数&#xff0c;我们就称这个区间 [i,j][i,j][i,…...

kubernetes集群部署springcloud项目【AL】【未写完】

kubernetes集群部署springcloud项目【AL】 &#xff08;先手工做&#xff0c;非自动化&#xff09; #环境&#xff1a; 192.168.73.138 master 192.168.73.139 node1 192.168.73.140 node2 192.168.73.137 harbor、mysqlgit clone https://github.com/lizhenliang/simple-…...

各种音频接口比较

时间 参考&#xff1a;https://www.bilibili.com/video/BV1SL4y1q7GZ/?spm_id_from333.337.search-card.all.click&vd_source00bd76f9d6dc090461cddd9f0deb2d51&#xff0c; https://blog.csdn.net/weixin_43794311/article/details/128941346 接口名字时间公司支持格式…...

软件测试面试理论(超详细)

【面试理论知识】1、你的测试职业发展是什么? 测试经验越多&#xff0c;测试能力越高。所以我的职业发展是需要时间积累的&#xff0c;一步步向着高级测试工程师奔去。而且我也有初步的职业规划&#xff0c;前3年积累测试经验&#xff0c;按如何做好测试工程师的要点去要求自己…...

c++学习笔记-二进制文件操作(哔站-黑马程序员c++教学视频)

一、基本概念 以二进制的方式对文件进行读写操作 打开方式指定为 ios::binary 优点&#xff1a;可以写入自己定义的数据类型 1、写文件 二进制方式写文件&#xff1a;流对象调用成员write 函数原型&#xff1a;ostream& write(const char * buffer,int len);参数解释…...

内网渗透(二十三)之Windows协议认证和密码抓取-Mimikatz介绍和各种模块使用方法

系列文章第一章节之基础知识篇 内网渗透(一)之基础知识-内网渗透介绍和概述 内网渗透(二)之基础知识-工作组介绍 内网渗透(三)之基础知识-域环境的介绍和优点 内网渗透(四)之基础知识-搭建域环境 内网渗透(五)之基础知识-Active Directory活动目录介绍和使用 内网渗透(六)之基…...

Nginx if的使用教程

if指令该指令用来支持条件判断&#xff0c;并根据条件判断结果选择不同的Nginx配置。语法if (condition){...}默认值—位置server、locationcondition为判定条件&#xff0c;可以支持以下写法&#xff1a;1. 变量名。如果变量名对应的值为空字符串或"0"&#xff0c;i…...

备考蓝桥杯【快速排序和归并排序】

&#x1f339;作者:云小逸 &#x1f4dd;个人主页:云小逸的主页 &#x1f4dd;Github:云小逸的Github &#x1f91f;motto:要敢于一个人默默的面对自己&#xff0c;强大自己才是核心。不要等到什么都没有了&#xff0c;才下定决心去做。种一颗树&#xff0c;最好的时间是十年前…...

Taro使用微信OCR插件无法调用onSuccess回调问题

Taro使用微信插件无法调用onSuccess回调问题小程序后台添加插件在开放社区购买相应的套餐详细步骤1.在app.config.js中添加如下代码2.在页面的page.config.js添加插件3.使用ocr-navigator识别身份证小程序后台添加插件 在开放社区购买相应的套餐 购买地址 详细步骤 1.在app.…...

【Java】代码块的细节你搞懂了吗(基础知识七)

希望像唠嗑一样&#xff0c;one step one futher。 目录 &#xff08;1&#xff09;代码块的应用场景 &#xff08;2&#xff09;代码块的细节 1.static 代码块只加载一次 2.当调用类的静态成员时&#xff0c;类会加载 3. 使用类的静态成员时&#xff0c;static代码块会被执…...

设计模式C++实现12:抽象工厂模式

参考大话设计模式&#xff1b; 详细内容参见大话设计模式一书第十五章&#xff0c;该书使用C#实现&#xff0c;本实验通过C语言实现。 抽象工厂模式&#xff08;Abstract Factory&#xff09;&#xff0c;提供一个创建一系列相关或相互依赖对象的接口&#xff0c;而无需指定它们…...

目标检测论文阅读:GraphFPN算法笔记

标题&#xff1a;GraphFPN: Graph Feature Pyramid Network for Object Detection 会议&#xff1a;ICCV2021 论文地址&#xff1a;https://ieeexplore.ieee.org/document/9710561/ Abstract 特征金字塔已经被证明在需要多尺度特征的图像理解任务中是强大的。SOTA的多尺度特征…...

实测2023款哪吒U-II,智驾功能对女司机很友好

最近&#xff0c;我们受邀试驾了2023款哪吒U-II。这是一款A级新能源SUV&#xff0c;是哪吒U的改款车型。哪吒U系列自2020年3月上市到2023年1月&#xff0c;累计销售数量达76688台&#xff0c;也因此被称为15万级智能天花板。2023款哪吒U-II的一大亮点是&#xff1a;针对以往哪吒…...

Python自动化测试【软件测试最全教程(附笔记、学习路线)】,看完即就业

最近看到很多粉丝在后台私信我&#xff0c;叫我做一期Python自动化测试的教程&#xff0c;其实关于这个问题&#xff0c;我也早就在着手准备了&#xff0c;我录制了一整套完整的Python自动化测试的教程&#xff0c;上传到网盘里了&#xff0c;大家有兴趣的可以去文末交流群免费…...

2023/2/13总结

今天主要学习了哈夫曼树。 哈夫曼树 哈夫曼树是二叉树的一种&#xff0c;它是一种WPL最优二叉树。 叶子结点&#xff08;也称叶节点&#xff09;&#xff1a;指的是自己下面不再连接有节点的节点&#xff08;即末端&#xff09;&#xff0c;称为叶子节点&#xff08;又称为终…...

Java响应式编程实战:用Reactor 3.x处理高并发请求(附完整代码示例)

Java响应式编程实战&#xff1a;用Reactor 3.x处理高并发请求&#xff08;附完整代码示例&#xff09; 在当今高并发的互联网应用中&#xff0c;传统的同步阻塞式编程模型往往成为性能瓶颈。想象一下&#xff0c;当你的电商系统在秒杀活动中面临每秒数万次的请求时&#xff0c;…...

SDMatte API接口开发教程:基于Python Flask构建标准化服务

SDMatte API接口开发教程&#xff1a;基于Python Flask构建标准化服务 1. 开篇&#xff1a;为什么需要API接口 如果你用过SDMatte这个强大的图像抠图工具&#xff0c;可能会遇到这样的场景&#xff1a;想把抠图功能集成到自己的应用里&#xff0c;或者需要批量处理大量图片。…...

axure-cn语言包:让Axure RP全版本界面无缝切换至中文的完整指南

axure-cn语言包&#xff1a;让Axure RP全版本界面无缝切换至中文的完整指南 【免费下载链接】axure-cn Chinese language file for Axure RP. Axure RP 简体中文语言包&#xff0c;不定期更新。支持 Axure 9、Axure 10。 项目地址: https://gitcode.com/gh_mirrors/ax/axure-…...

Uvicorn与Scaleway Serverless Functions:无服务器Python应用部署终极指南

Uvicorn与Scaleway Serverless Functions&#xff1a;无服务器Python应用部署终极指南 【免费下载链接】uvicorn An ASGI web server, for Python. &#x1f984; 项目地址: https://gitcode.com/GitHub_Trending/uv/uvicorn Uvicorn作为Python生态中最快、最现代的ASGI…...

如何为你的单片机项目选择最佳通信协议?I²C、SPI、UART全解析

单片机通信协议深度指南&#xff1a;从理论到实战的精准选择策略 当你的单片机需要与外部世界对话时&#xff0c;选择正确的通信协议就像为不同场合挑选合适的语言——商务会议需要正式严谨&#xff0c;朋友聊天则讲究轻松随意。在嵌入式系统设计中&#xff0c;UART、IC和SPI这…...

手把手教你用Python+AI大模型,把Yapi接口文档变成自动化测试脚本(附避坑指南)

用Python与大模型实现Yapi接口自动化测试的工程化实践 在中小型技术团队中&#xff0c;接口测试往往是质量保障的薄弱环节。传统手工编写测试用例的方式不仅耗时耗力&#xff0c;更难以应对快速迭代的开发节奏。本文将分享如何利用Python生态与AI大模型能力&#xff0c;将Yapi平…...

5G NR物理层实战:如何利用TS 38.211优化无线资源管理

5G NR物理层实战&#xff1a;TS 38.211无线资源管理优化指南 在5G网络部署的深水区&#xff0c;无线资源管理&#xff08;RRM&#xff09;的精细化程度直接决定了网络性能天花板。作为3GPP物理层协议集的核心文档&#xff0c;TS 38.211规范中隐藏着诸多未被充分挖掘的优化密钥—…...

新手别怕!用Vivado仿真Verilog的8个经典电路,从JK触发器到频率计保姆级复盘

Vivado实战&#xff1a;从JK触发器到频率计的Verilog仿真全指南 刚接触FPGA开发的同学们&#xff0c;是否经常遇到这样的困境&#xff1a;明明理解了Verilog语法&#xff0c;却在Vivado仿真时频频报错&#xff1f;或是仿真波形与预期完全不符&#xff0c;却找不到问题所在&…...

ADRV9009+ZCU102实战:从HDL工程构建到no-OS移植的5个关键步骤

ADRV9009ZCU102全流程开发指南&#xff1a;从HDL工程构建到no-OS移植的深度实践 在射频系统开发领域&#xff0c;ADRV9009作为一款高性能射频收发器&#xff0c;与Xilinx ZCU102开发板的组合已成为许多硬件工程师的首选方案。本文将深入剖析五个关键环节的技术细节&#xff0c;…...

告别Keil?STM32CubeIDE环境搭建全记录:附JAVA安装与汉化资源指北

从Keil到STM32CubeIDE&#xff1a;嵌入式开发环境迁移实战指南 当ST官方逐渐将重心转向HAL库生态时&#xff0c;许多传统开发者正面临工具链升级的抉择。作为一款集成了STM32CubeMX功能的Eclipse-based IDE&#xff0c;STM32CubeIDE不仅代表着开发模式的转变&#xff0c;更预示…...