B201-SpringBoot整合Shiro

目录

      • Shiro
      • Shiro核心组件
      • SpringBoot整合Shiro
        • 1.创建新SpringBoot项目和导包
        • 2.自定义Shiro过滤器Realm
        • 3.配置类ShiroConfig
        • 编写认证和授权规则案例:
          • 案例思路
          • 改造ShiroConfig
          • AccountController
          • 配置视图解析器
          • templates下新建3个页面
          • 启动测试
        • 登录认证
          • 设置自定义登录页面
          • 写登录接口
          • 测试效果
        • 授权
        • 设置未授权异常响应
        • 登录后显示欢迎信息
        • 退出登录
        • 动态菜单
      • tips:

Shiro

什么是 Shiro

官网:http://shiro.apache.org/

是一款主流的 Java 安全框架,不依赖任何容器,可以运行在 Java SE 和 Java EE 项目中,它的主要作用是对访问系统的用户进行身份认证、授权、会话管理、加密等操作。

Shiro 就是用来解决安全管理的系统化框架。

Shiro核心组件

1.UsernamePasswordToken:
(封装了用户名和密码的token)
Shiro 用来封装用户登录信息,使用用户的登录信息来创建令牌 Token。
(把用户名和密码传入token,交给shiro,让shiro去登录认证和权限校验)

2、Suject:Shiro 的一个抽象概念,包含了用户信息。
(相当于包含了用户信息的一个载体,系统可通过Suject取用户信息)

3、SecurityManager:Shiro 的核心部分,负责安全认证和授权。
(上面只是封装,具体操作由它完成)

4、AuthenticationInfo:用户的角色信息集合,认证时使用。
(用户、角色、权限,会给角色赋予权限,给用户赋予角色)
在这里插入图片描述
5、AuthorizationInfo:角色的权限信息集合,授权时使用。

6、Realm:开发者自定义的模块,根据项目的需求,验证和授权的逻辑全部写在 Realm 中。

7、DefaultWebSecurityManager:安全管理器,开发者自定义的 Realm 需要注入到 DefaultWebSecurityManager 进行管理才能生效。

8、ShiroFilterFactoryBean:过滤器工厂,Shiro 的基本运行机制是开发者定制规则(怎么拦截请求,怎么认证,怎么授权,告诉shiro),Shiro 去执行,具体的执行操作就是由 ShiroFilterFactoryBean 创建的一个个 Filter 对象来完成。

Shiro 的运行机制如下图所示。
在这里插入图片描述

SpringBoot整合Shiro

1.创建新SpringBoot项目和导包
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>1.5.3</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.3.1.tmp</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency>
</dependencies>
2.自定义Shiro过滤器Realm
public class AccoutRealm extends AuthorizingRealm {@Autowiredprivate AccountService accountService;/*** 登录认证:用户名和密码校验* @param authenticationToken* @return* @throws AuthenticationException*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;Account account = accountService.findByUsername(token.getUsername());if(account != null){return new SimpleAuthenticationInfo(account,account.getPassword(),getName());}return null;}/*** 授权* @param principalCollection* @return*/@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {return null;}
}
3.配置类ShiroConfig
@Configuration
public class ShiroConfig {@Bean // 创建对象并放入容器public AccoutRealm accoutRealm(){return new AccoutRealm();}@Bean   // @Qualifier("accoutRealm"):根据方法名从ioc容器中取beanpublic DefaultWebSecurityManager securityManager(@Qualifier("accoutRealm") AccoutRealm accoutRealm){DefaultWebSecurityManager manager = new DefaultWebSecurityManager();manager.setRealm(accoutRealm);return manager;}@Bean   // @Qualifier("securityManager"):根据方法名从ioc容器中取beanpublic ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();factoryBean.setSecurityManager(securityManager);return factoryBean;}
}
编写认证和授权规则案例:

认证过滤器选项:

anon:无需认证。
authc:必须认证。
authcBasic:需要通过 HTTPBasic 认证。
user:不一定通过认证,只要曾经被 Shiro 记录即可,比如:记住我。

授权过滤器选项:

perms:必须拥有某个权限才能访问。
role:必须拥有某个角色才能访问。
port:请求的端口必须是指定值才可以。
rest:请求必须基于 RESTful,POST、PUT、GET、DELETE。
ssl:必须是安全的 URL 请求,协议 HTTPS。

案例思路

创建 3 个页面:main.html、manage.html、administrator.html,访问权限如下:
1、必须登录才能访问 main.html
2、当前用户必须拥有 manage 授权才能访问 manage.html
3、当前用户必须拥有 administrator 角色才能访问 administrator.html

改造ShiroConfig
    @Bean   // @Qualifier("securityManager"):根据方法名从ioc容器中取beanpublic ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();factoryBean.setSecurityManager(securityManager);//权限设置Map<String,String> map = new Hashtable<>();map.put("/main","authc");           //请求main.html时必须为登录状态map.put("/manage","perms[manage]");         //请求manage.html时必须有manage权限map.put("/administrator","roles[administrator]");    //请求administrator.html时必须有administrator角色factoryBean.setFilterChainDefinitionMap(map);      //根据map创建对应的过滤器,去拦截和校验return factoryBean;}
AccountController
@Controller
public class AccountController {@GetMapping("/{url}")public String redirect(@PathVariable("url") String url){return url;}
}
配置视图解析器
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: rooturl: jdbc:mysql://localhost:3306/shiro?serverTimezone=UTCthymeleaf:  #配置视图解析器prefix: classpath:/templates/suffix: .html
mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
templates下新建3个页面

main.html、manage.html、administrator.html

启动测试

浏览器访问http://localhost:8080/main会报500并跳到http://localhost:8080/login.jsp

tips:页面加入以下代码可消除不影响运行的报错

<link rel="shortcut icon" href="#"/>
登录认证
设置自定义登录页面

ShiroConfig

    @Bean   // @Qualifier("securityManager"):根据方法名从ioc容器中取beanpublic ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();factoryBean.setSecurityManager(securityManager);//权限设置Map<String,String> map = new Hashtable<>();map.put("/main","authc");           //请求main.html时必须为登录状态map.put("/manage","perms[manage]");         //请求manage.html时必须有manage权限map.put("/administrator","roles[administrator]");    //请求administrator.html时必须有administrator角色factoryBean.setFilterChainDefinitionMap(map);      //根据map创建对应的过滤器,去拦截和校验//设置去登录页面的后端get请求  不走默认的login.jsp,发后端请求经视图解析器走到login.htmlfactoryBean.setLoginUrl("/login");
//        //设置未授权页面
//        factoryBean.setUnauthorizedUrl("/unauth");return factoryBean;}

login.html

<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Title</title><link rel="shortcut icon" href="#"/>
</head>
<body><form action="/login" method="post"><table><span th:text="${msg}" style="color: red"></span><tr><td>用户名:</td><td><input type="text" name="username"/></td></tr><tr><td>密码:</td><td><input type="password" name="password"/></td></tr><tr><td><input type="submit" value="登录"/></td></tr></table></form>
</body>
</html>
写登录接口

AccountController

    @PostMapping("/login")public String login(String username, String password, Model model){Subject subject = SecurityUtils.getSubject();UsernamePasswordToken token = new UsernamePasswordToken(username,password);try {subject.login(token); //会走去realm里认证
//            Account account = (Account) subject.getPrincipal();
//            subject.getSession().setAttribute("account",account);return "index";} catch (UnknownAccountException e) {e.printStackTrace();model.addAttribute("msg","用户名错误!");return "login";} catch (IncorrectCredentialsException e){model.addAttribute("msg","密码错误!");e.printStackTrace();return "login";}}
测试效果

1.浏览器输入http://localhost:8080/index进入index页面
在这里插入图片描述
2.index页面点击main进入登录页面
在这里插入图片描述
3.登录进入首页,然后可以访问main了
在这里插入图片描述

授权

从数据库取出角色和权限信息设置到框架中
注意:案例里用户的角色和权限都是单个的
AccoutRealm

    /*** 授权* @param principalCollection* @return*/@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {//获取当前登录的用户信息Subject subject = SecurityUtils.getSubject();Account account = (Account) subject.getPrincipal();//设置角色Set<String> roles = new HashSet<>();roles.add(account.getRole());SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roles);//设置权限info.addStringPermission(account.getPerms());return info;}

重新启动测试:分别用不同用户访问不同页面

设置未授权异常响应

ShiroConfig添加代码

    @Bean   // @Qualifier("securityManager"):根据方法名从ioc容器中取beanpublic ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();factoryBean.setSecurityManager(securityManager);//权限设置Map<String,String> map = new Hashtable<>();map.put("/main","authc");           //请求main.html时必须为登录状态map.put("/manage","perms[manage]");         //请求manage.html时必须有manage权限map.put("/administrator","roles[administrator]");    //请求administrator.html时必须有administrator角色factoryBean.setFilterChainDefinitionMap(map);      //根据map创建对应的过滤器,去拦截和校验//设置去登录页面的后端get请求  不走默认的login.jsp,发后端请求经视图解析器走到login.htmlfactoryBean.setLoginUrl("/login");//设置处理未授权异常的get接口factoryBean.setUnauthorizedUrl("/unauth");return factoryBean;}

AccountController添加代码

    @GetMapping("/unauth")@ResponseBodypublic String unauth(){return "未授权,无法访问!";}
登录后显示欢迎信息

后台登录后把用户信息存进session
在这里插入图片描述
index页面取出用户名显示
在这里插入图片描述

退出登录

index.html添加代码
在这里插入图片描述
后端AccountController添加代码

    @GetMapping("/logout")public String logout(){Subject subject = SecurityUtils.getSubject();subject.logout();return "login";}
动态菜单

1、pom.xml 引入依赖

<dependency><groupId>com.github.theborakompanioni</groupId><artifactId>thymeleaf-extras-shiro</artifactId><version>2.0.0</version>
</dependency>

2、配置类 ShiroConfig 添加 ShiroDialect 方言

@Bean
public ShiroDialect shiroDialect(){return new ShiroDialect();
}

3、index.html
在这里插入图片描述

tips:

idea不识别已导入依赖?
1.maven clean install,2.pom 剪切 粘贴,3.重启idea

Mapper注入报红?
因为是用的动态代理对象,运行后ioc容器里面才会有,不影响运行,也可以用@Repository解决

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

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

相关文章

Go的数据结构与实现【Graph】

介绍 图是网络结构的表示。现实世界中有大量图谱示例&#xff0c;互联网和社交图谱就是经典示例。图基本上是一组由边连接的节点。 实现 实现思路 图形数据结构将实现这些方法&#xff1a; AddNode()&#xff1a;添加一个节点到图里 AddEdge()&#xff1a;添加一条边到图里…

【C++庖丁解牛】自平衡二叉搜索树--AVL树

&#x1f341;你好&#xff0c;我是 RO-BERRY &#x1f4d7; 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f384;感谢你的陪伴与支持 &#xff0c;故事既有了开头&#xff0c;就要画上一个完美的句号&#xff0c;让我们一起加油 目录 前言1 AVL树的概念2. AVL…

探索未来的视觉智能:AI视频分析系统的崭新时代

随着人工智能技术的飞速发展&#xff0c;AI视频分析系统正逐渐成为各行业的关注焦点。这些系统不仅可以帮助安防领域实现更智能化的监控&#xff0c;还能在零售、交通、医疗等领域发挥重要作用。本文将深入探讨AI视频分析系统的崭新时代&#xff0c;揭示其未来发展的无限可能。…

曼哈顿距离转化为切比雪夫距离

目录 1 介绍2 训练3 参考 1 介绍 本专题介绍曼哈顿距离如何转化为切比雪夫距离。 A点 ( x 1 , y 1 ) (x_1,y_1) (x1​,y1​)和B点 ( x 2 , y 2 ) (x_2,y_2) (x2​,y2​)的曼哈顿距离定义为它们的坐标差绝对值之和&#xff0c;即 ∣ x 1 − x 2 ∣ ∣ y 1 − y 2 ∣ |x_1-x_…

2-HDFS常用命令及上传下载流程

HDFS NameNode 安全模式(safemode) 当NameNode被重启的时候&#xff0c;自动进入安全模式 在安全模式中&#xff0c;NameNode首先会触发edits_inprogress文件的滚动。滚动完成之后&#xff0c;更新fsimage文件 更新完成之后&#xff0c;NameNode会将fsimage文件中的元数据加…

利用python做模拟数据(测试数据),连接数据库和服务器接口,涉及雪花id服务

import datetime import jsonimport pymysql import requests import snowflake.client from faker import Faker#cmd启动snowflake服务&#xff1a; #snowflake_start_server --addresslocalhost --port8910 --dc1 --worker1 def create_testers():# 创建一个中文Faker实例fak…

Python 判断当前操作系统的几种方法

本文介绍 Python 判断操作系统的3种方法。以下的方法将分为这几部分&#xff1a; Python os.namePython sys.platformPython platform.system() Python os.name Python 判断操作系统的方法可以使用 os.name&#xff0c;这里以 Python 3 为例&#xff0c;os.name 会返回 posi…

基于java+SpringBoot+Vue的网上书城管理系统设计与实现

基于javaSpringBootVue的网上书城管理系统设计与实现 开发语言: Java 数据库: MySQL技术: SpringBoot MyBatis工具: IDEA/Eclipse、Navicat、Maven 系统展示 前台展示 后台展示 系统简介 整体功能包含&#xff1a; 网上书城管理系统是一个基于互联网的在线购书平台&#…

文献学习-23-MRM:用于遗传学医学图像预训练的掩码关系建模

MRM: Masked Relation Modeling for Medical Image Pre-Training with Genetics Authors: Qiushi Yang, Wuyang Li, Baopu Li, Yixuan Yuan Source: ICCV 2023 Abstract: 关于自动多模态医疗诊断的 ODERN 深度学习技术依赖于大量的专家注释&#xff0c;这既耗时又令人望而却…

【Spring MVC】快速学习使用Spring MVC的注解及三层架构

&#x1f493; 博客主页&#xff1a;从零开始的-CodeNinja之路 ⏩ 收录文章&#xff1a;【Spring MVC】快速学习使用Spring MVC的注解及三层架构 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 Spring Web MVC一: 什么是Spring Web MVC&#xff1…

何时应用 RAG 与微调

充分发挥 LLM 的潜力需要在检索增强生成&#xff08;RAG&#xff09;和微调之间选择正确的技术。 让我们来看看何时对 LLM、较小的模型和预训练模型使用 RAG 与微调。我们将介绍&#xff1a; LLM 和 RAG 的简要背景RAG 相对于微调 LLM 的优势何时针对不同模型大小对 RAG 进行…

python 贪吃蛇

main.py #!/usr/bin/env python3 # -*- coding: utf-8 -*-import pygame # 导入pygame模块from setting import Setting import startmain as sm from pygame.sprite import Groupdef InitGame():print("InitGame")pygame.init() #初始化pygameai_settings Se…

【图轮】【 最小生成树】【 并集查找】1489. 找到最小生成树里的关键边和伪关键边

本文涉及知识点 图轮 最小生成树 并集查找 关键边 1489. 找到最小生成树里的关键边和伪关键边 给你一个 n 个点的带权无向连通图&#xff0c;节点编号为 0 到 n-1 &#xff0c;同时还有一个数组 edges &#xff0c;其中 edges[i] [fromi, toi, weighti] 表示在 fromi 和 to…

书生·浦语全链路开源开放体系 第二期

文章目录 大模型背景大模型开发流程InternLM 2.0SFT与RLHFInternLM2主要亮点 书生浦语全链路开源开放体系数据-书生万卷InternLM-Train微调 XTuner评测工具 OpenCompass部署 LMDeploy智能体 Lagent智能体工具箱 AgentLego 大模型背景 专用模型&#xff1a;针对特定的任务&…

【Web】NSSCTF Round#20 Basic 个人wp

目录 前言 真亦假&#xff0c;假亦真 CSDN_To_PDF V1.2 前言 感谢17&#x1f474;没让我爆零 真亦假&#xff0c;假亦真 直接getshell不行&#xff0c;那就一波信息搜集呗&#xff0c;先开dirsearch扫一下 扫的过程中先试试常规的robots.txt,www.zip,shell.phps,.git,.sv…

使用Docker Compose一键部署前后端分离项目(图文保姆级教程)

一、安装Docker和docker Compose 1.Docker安装 //下载containerd.io包 yum install https://download.docker.com/linux/fedora/30/x86_64/stable/Packages/containerd.io-1.2.6-3.3.fc30.x86_64.rpm //安装依赖项 yum install -y yum-utils device-mapper-persistent-data l…

求整数各个数位上的数字之和 C语言

对于任意输入的整数&#xff0c;计算其各个数位上的数字之和。 输入格式 输入一个正整数 N。 输出格式 输出 N 的各个位上的数字之和。 数据范围 1 < N < 2^31 #include <stdio.h> #include <stdlib.h> int shu(int x){ int sum0; while(x>0)…

百度云加速方法「Cheat Engine」

加速网盘下载 相信经常玩游戏的小伙伴都知道「Cheat Engine」这款游戏内存修改器&#xff0c;它除了能对游戏进行内存扫描、调试、反汇编 之外&#xff0c;还能像变速齿轮那样进行本地加速。 这款专注游戏的修改器&#xff0c;被大神发现竟然还能加速百度网盘资源下载&#xf…

c++前言

目录 1. 什么是 C 2. C 发展史 3. C 的重要性 4. 如何学习 C 5. 关于本门课程 1. 什么是C C语言是结构化和模块化的语言&#xff0c;适合处理较小规模的程序。对于复杂的问题&#xff0c;规模较大的 程序&#xff0c;需要高度的抽象和建模时&#xff0c; C 语言则不合适…

【JavaParser笔记01】JavaParser解析Java源代码中的类信息(javadoc注释、类​​​​​​​名称)

这篇文章,主要介绍如何使用JavaParser解析Java源代码中的类信息(javadoc注释、类名称)。 目录 一、JavaParser依赖库 1.1、引入依赖 1.2、获取类注释信息