shiro入门
1、概述
Apache Shiro 是一个功能强大且易于使用的 Java 安全(权限)框架。借助 Shiro 您可以快速轻松地保护任何应用程序一一从最小的移动应用程序到最大的 Web 和企业应用程序。
作用:Shiro可以帮我们完成 :认证、授权、加密、会话管理、与 Web 集成、缓存等。
2、Shiro 与 SpringSecurity 的对比
- 1、Spring Security 基于 pring 开发,项目若使用 Spring 作为基础,配合 SpringSecurity 做权限更加方便,而 Shiro需要和 Spring 进行整合开发;
- 2、Spring Security 功能比 Shiro 更加丰富些,例如安全维护方面;
- 3、Spring Security 社区资源相对比 Shiro 更加丰富:;
- 4、Shiro的配置和使用比较简单,Spring Security 上手复杂些;
- 5、Shiro 依赖性低,不需要任何框架和容器,可以独立运行.Spring Security 依赖Spring容器;
- 6、shiro 不仅仅可以使用在 web 中,它可以工作在任何应用环境中。在集群会话时 Shiro最重要的一个好处或许就是它的会话是独立于容器的;
3、Shiro核心架构

Subject即主体,外部应用与subject进行交互,subject记录了当前的操作用户,将用户的概念理解为当前操作的主体。外部程序通过subject进行认证授权,而subject是通过SecurityManager安全管理器进行认证授权
SecurityManager即安全管理器,对全部的subject进行安全管理,它是shiro的核心,负责对所有的subject进行安全管理。通过SecurityManager可以完成subject的认证、授权等,实质上SecurityManager是通过Authenticator进行认证,通过Authorizer进行授权,通过SessionManager进行会话管理等
SecurityManager是一个接口,继承了Authenticator, Authorizer, SessionManager这三个接口
Authenticator即认证器,对用户身份进行认证,Authenticator是一个接口,shiro提供ModularRealmAuthenticator实现类,通过ModularRealmAuthenticator基本上可以满足大多数需求,也可以自定义认证器
Authorizer即授权器,用户通过认证器认证通过,在访问功能时需要通过授权器判断用户是否有此功能的操作权限
Realm即领域,相当于datasource数据源,securityManager进行安全认证需要通过Realm获取用户权限数据,比如:如果用户身份数据在数据库那么realm就需要从数据库获取用户身份信息
sessionManager即会话管理,shiro框架定义了一套会话管理,它不依赖web容器的session,所以shiro可以使用在非web应用上,也可以将分布式应用的会话集中在一点管理,此特性可使它实现单点登录
SessionDAO即会话dao,是对session会话操作的一套接口,比如要将session存储到数据库,可以通过jdbc将会话存储到数据库
CacheManager即缓存管理,将用户权限数据存储在缓存,这样可以提高性能Cryptography
Cryptography即密码管理,shiro提供了一套加密/解密的组件,方便开发。比如提供常用的散列、加/解密等功能。
token
1、token定义:服务端生成的一串字符串,可以解决频繁登录的问题
作为客户端进行请求的一个令牌:
- 第一次登录后,服务器生成一个token返回给客户端;
- 客户端只需要带上token来请求数据即可,无需再次带上用户名和密码;
2、目的:为了减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮
4、Shiro的登录认证
1.创建数据库并创建用户表;
2.创建项目病配置ssm,完成根据用户名查询用户信息;
3.创建自定义Realm,继承AuthorizingRealm,使用mybtais查询数据库的盐值和密码,交给shiro进行验证;
流程

1.数据库与表创建
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (`uid` int(11) NOT NULL AUTO_INCREMENT,`uname` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,`pwd` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,`sex` varchar(2) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,`address` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,`state` int(2) DEFAULT NULL,`salt` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,PRIMARY KEY (`uid`) USING BTREE,UNIQUE INDEX `uname`(`uname`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, 'admin', '727d8b2b4c59366d7ace58d4eda4cfee', '女', '河南洛阳', 1, '9C2AB20283F9450389330033D64686DD');
INSERT INTO `user` VALUES (2, 'zs', '83f12ba7c4357b87167e240a22c15248', '男', '河南郑州', 1, '262F995823C94D1CAE7596B47E8AB657');select * from user
2.创建模块项目,使用maven+ssm+shiro


3.搭建ssm框架,编写根据用户名查询用户信息的三层架构
shiro在spring.xml中的配置

dao层
@Repository
public interface UserDao {@Select("select * from user where uname = #{uname}")User selectByName(String uname);
}
service层
public interface UserService {User selectByName(String uname);
}
实现类
@Service
public class UserServiceImpl implements UserService {@AutowiredUserDao userDao;@Overridepublic User selectByName(String uname) {return userDao.selectByName(uname);}
}
controller层进行shiro认证
@Controller
public class UserController {@RequestMapping("/login")public String login(String uname, String pwd, HttpSession session){//1 获取 Subject 对象Subject subject = SecurityUtils.getSubject();//2 封装请求数据到 token 对象中AuthenticationToken token = new UsernamePasswordToken(uname,pwd);//3 调用 login 方法进行登录认证try{//验证主体是否能够登录subject.login(token);session.setAttribute("user",token.getPrincipal().toString());return "main";}catch(UnknownAccountException e){System.out.println("用户名不存在!!");return "login";}catch(IncorrectCredentialsException e){System.out.println("密码错误!");return "login";}catch(AuthenticationException e){System.out.println("登录失败!");return "login";}}
}
/*** 地址和页面的映射,项目中没有页面请求,全是地址请求*/
@Controller
public class PageController {@RequestMapping({"/","/index"})public String index(){return "index";}@RequestMapping("/loginUI")public String home(){return "login";}@RequestMapping("/main")public String phone(){return "main";}}
web.xml中配置shiro的过滤器
<!-- shiro配置 -->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filterclass>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
shiro层测试
public class Shiro01 {public static void main(String[] args) {
// //Java加盐加密
// Digester md5 = new Digester(DigestAlgorithm.MD5);
// md5.setSalt("9C2AB20283F9450389330033D64686DD".getBytes());//加盐
// md5.setDigestCount(1024);//加散列值
// String md5Pwd = md5.digestHex("123");
// System.out.println(md5Pwd);//控制台获取Scanner sc = new Scanner(System.in);System.out.println("请输入用户名:");String username = sc.next();System.out.println("请输入密码:");String password = sc.next();//1.使用INi格式工厂模型来创建对象IniSecurityManagerFactory securityManagerFactory = new IniSecurityManagerFactory("classpath:shiro.ini");//2.获取安全管理器SecurityManager securityManager = securityManagerFactory.getInstance();//3.让安全管理器开始工作SecurityUtils.setSecurityManager(securityManager);//4.获取系统访问的主体:就是登录系统的用户信息Subject subject = SecurityUtils.getSubject();//4.1模拟客户端传输过来的用户名和密码---创建对应的令牌 tokenAuthenticationToken token = new UsernamePasswordToken(username,password);try{//5.验证主体是否能够登录subject.login(token);System.out.println("登录成功!");}catch(UnknownAccountException e){System.out.println("用户名不存在!!");}catch(IncorrectCredentialsException e){System.out.println("密码错误!");}catch(AuthenticationException e){System.out.println("认证失败,不知道出了什么问题!");}}
}
创建MyRealm继承AuthorizingRealm
package com.zhan.shiro;import com.zhan.bean.User;
import com.zhan.service.UserService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;/*** token 里面是客户端发来的信息(包含输入的用户名和密码* 自定义Realm,通过mybatis查询数据库的密码和盐值,让shiro进行身份验证*/
@Component
public class MyRealm extends AuthorizingRealm {@AutowiredUserService userService;/*** shiro 进行授权操作* @param principals* @return*/@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {return null;}/*** shiro 进行认证操作* @param token* @return* @throws AuthenticationException*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {//token 是主体传过来的身份令牌//1.获取用户身份信息String uname = token.getPrincipal().toString();//2.调用业务层获取永固信息(数据库中)User user = userService.selectByName(uname);//判断并将数据完成封装if(user!=null){AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(token.getPrincipal(),//令牌身份信息对象user.getPwd(),//用户数据库的密码ByteSource.Util.bytes(user.getSalt().getBytes()),//加密时的盐值uname//用户名);return authenticationInfo;}return null;}
}
相关文章:
shiro入门
1、概述 Apache Shiro 是一个功能强大且易于使用的 Java 安全(权限)框架。借助 Shiro 您可以快速轻松地保护任何应用程序一一从最小的移动应用程序到最大的 Web 和企业应用程序。 作用:Shiro可以帮我们完成 :认证、授权、加密、会话管理、与 Web 集成、…...
开源 sysgrok — 用于分析、理解和优化系统的人工智能助手
作者:Sean Heelan 在这篇文章中,我将介绍 sysgrok,这是一个研究原型,我们正在研究大型语言模型 (LLM)(例如 OpenAI 的 GPT 模型)如何应用于性能优化、根本原因分析和系统工程领域的问题。 你可以在 GitHub …...
Gitlab保护分支与合并请求
目录 引言 1、成员角色指定 1、保护分支设置 2、合并请求 引言 熟悉了Git工作流之后,有几个重要的分支,如Master(改名为Main)、Develop、Release分支等,是禁止开发成员随意合并和提交的,在此分支上的提交和推送权限仅限项目负责…...
ad18学习笔记九:输出文件
一般来说提供给板卡厂的文件里要包括以下这些文件 1、装配图 2、bom文件 3、gerber文件 4、转孔文件 5、坐标文件 6、ipc网表 AD_PCB:Gerber等各类文件的输出 - 哔哩哔哩 原点|钻孔_硬件设计AD 生成 Gerber 文件 1、装配图 如何输出装配图? 【…...
PostgreSQL 内存配置 与 MemoryContext 的生命周期
PostgreSQL 内存配置与MemoryContext的生命周期 PG/GP 内存配置 数据库可用的内存 gp_vmem 整个 GP 数据库可用的内存 gp_vmem: >>> RAM 128 * GB >>> gp_vmem ((SWAP RAM) - (7.5*GB 0.05 * RAM)) / 1.7 >>> print(gp_vmem / G…...
vue3 组件间通信的方式(setup语法糖写法)
vue3 组件间通信的方式(setup语法糖写法) 1. Props方式 该方式用于父传子,父组件以数据绑定的形式声明要传递的数据,子组件通过defineProps()方法创建props对象,即可拿到父组件传来的数据。 // 父组件 <template><div><son…...
【Cache】Rsync远程同步
文章目录 一、rsync 概念二、rysnc 服务器部署1. 环境配置2. rysnc 同步源服务器2.1 安装 rsync2.2 建立 rsyncd.conf 配置文件2.3 创建数据文件(账号密码)2.4 启动服务2.5 数据配置 3. rysnc 客户端3.1 设置同步方法一方法二 3.2 免交互设置 4. rysnc 认…...
Gitlab升级报错一:rails_migration[gitlab-rails] (gitlab::database_migrations line 51)
Gitlab-ce从V14.0.12升级到V14.3.6或V14.10.5时报错:如下图: 解决办法: 先停掉gitlab: gitlab-ctl stop 单独启动数据库,如果不单独启动数据库,就会报以上错误 sudo gitlab-ctl start postgresql 解决办法&#x…...
chatGPT流式回复是怎么实现的
chatGPT流式回复是怎么实现的 先说结论: chatGPT的流式回复用的就是HTTP请求方案中的server-send-event流式接口,也就是服务端向客户端推流数据。 那eventStream流式接口怎么实现呢,下面就进入正题! 文章目录 chatGPT流式回复…...
使用SpringEL获得字符串中的表达式运算结果
概述 有时候会遇上奇怪的需求,比如解析字符串中表达式的结果。 这个时候自己写解析肯定是比较麻烦的, 正好SprinngEL支持加()、减(-)、乘(*)、除(/)、求余(%)、幂(^)运算,可以免去造轮子的功夫…...
力扣 39. 组合总和
题目来源:https://leetcode.cn/problems/combination-sum/description/ C题解: 递归法。递归前对数组进行有序排序,可方便后续剪枝操作。 递归函数参数:定义两个全局变量,二维数组result存放结果集,数组pa…...
基于BES系列蓝牙耳机NTC充电电池保护电路设计
+hezkz17进数字音频系统研究开发交流答疑 一 在充电电路中NTC作用? 在充电电路中,NTC(Negative Temperature Coefficient)热敏电阻通常被用于温度检测和保护。它具有随温度变化而变化的电阻值。 以下是NTC在充电电路中的几种常见作用: 温度监测:NTC热敏电阻可以用来测量…...
13-C++算法笔记-递归
📚 Introduction 递归是一种常用的算法设计和问题求解方法。它基于问题可以分解为相同类型的子问题,并通过解决子问题来解决原始问题的思想。递归算法在实际编程中具有广泛的应用。 🎯 递归算法解决问题的特点 递归算法具有以下特点&#…...
从古代八卦探究计算机的八进制
八进制,即八卦,是中国古代哲学体系中非常重要的一个概念,它被广泛应用于易经、道家、儒家等诸多领域。随着计算机科学的快速发展,人们开始思考:八进制是否可以应用到计算机上? 一、什么是八进制࿱…...
Linux shell mkfs.ext4命令参数使用
mkfs mkfs是个综合命令 mkfs 然后按两下tab 查看系统支持哪些文件系统的格式化功能 mkfs -t 文件系统格式名 以指定的文件系统格式来进行磁盘格式化 > 等于 mkfs.文件系统格式名 比如: mkfs -t xfs mkfs.xfs 常见的磁盘格式…...
【Docker】子系统与其相关名词的界定、Control Groups等详细讲解
前言 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。 📕作者简介:热…...
spring事务的传播性与隔离性
spring事务的传播性 REQUIRED(必须的)(TransactionDefinition.PROPAGATION_REQUIRED) 使用当前的事务,如果当前没有事务,则自己新建一个事务,子方法是必须运行在一个事务中的,如果当前存在事务,…...
【设计模式】模板方法与策略模式的结合使用
文章目录 1. 概述1.1.简述模板方法 2.模板方法实现2.1.简单实现2.2.在SpringBoot中的实现 3.模板方法与策略模式的结合使用3.1.代码实现 4.总结 1. 概述 模板方法是一种非常简单的设计模式,只要能够理解面向对象中的继承与多态就能够理解这种设计模式,我…...
Jmeter实现参数加密
目录 一、使用__digest自带函数 以md5加密算法演示使用方法 二、在BeanShell 中使用JAVA代码实现算法加密 规避BUG的方法 JMeter有两种方法可以实现算法加密 一、使用__digest自带函数 参数说明: Digest algorithm:算法摘要,可输入值&a…...
Solon Web 开发:四、认识请求上下文(Context)
Handler Context 架构,是Solon Web 的基础。在 Context (org.noear.solon.core.handle.Context)里可以获取: 请求相关的对象与接口会话状态相关的对象与接口响应相关的对象与接口 或者理解所有请求与响应相关的,都在…...
多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...
