Shiro认证

1. Shiro简介

Shiro是一个强大且灵活的Java安全框架,专注于认证、授权、加密、会话管理等功能,能够无缝集成到现有的应用程序中。相比Spring Security,Shiro的学习曲线较为平缓,配置简单

(1) Shiro特性
  • 认证(Authentication):身份验证,确认用户的身份信息
  • 授权(Authorization):基于角色或权限控制访问资源
  • 会话管理(Session Management):支持JavaSE和JavaEE环境下的会话管理
  • 加密(Cryptography):提供用于安全操作的加密API
  • 易扩展性:Shiro的各个模块是解耦的,开发者可以根据需要进行灵活扩展
(2) Shiro架构

Shiro的核心架构主要由以下几部分组成:

  • Subject:表示当前用户,包括已登录和未登录的用户
  • SecurityManager:Shiro的核心控制器,管理所有安全操作,相当于Spring Security中的Filter Chain
  • Realm:用于连接实际数据源(如数据库)和Shiro,负责根据用户凭证获取相应的权限、角色信息
2. 认证(Authentication)

认证是Shiro中的一个重要部分,主要验证用户的身份

(1) Token

Shiro中的认证是基于令牌(Token)的,最常用的令牌是UsernamePasswordToken,它包含用户名和密码,用于在登录时进行身份验证

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package org.apache.shiro.authc;public class UsernamePasswordToken implements HostAuthenticationToken, RememberMeAuthenticationToken {private String username;private char[] password;private boolean rememberMe;private String host;public UsernamePasswordToken() {this.rememberMe = false;}public UsernamePasswordToken(String username, char[] password) {this(username, (char[])password, false, (String)null);}public UsernamePasswordToken(String username, String password) {this(username, (char[])(password != null ? password.toCharArray() : null), false, (String)null);}public UsernamePasswordToken(String username, char[] password, String host) {this(username, password, false, host);}public UsernamePasswordToken(String username, String password, String host) {this(username, password != null ? password.toCharArray() : null, false, host);}public UsernamePasswordToken(String username, char[] password, boolean rememberMe) {this(username, (char[])password, rememberMe, (String)null);}public UsernamePasswordToken(String username, String password, boolean rememberMe) {this(username, (char[])(password != null ? password.toCharArray() : null), rememberMe, (String)null);}public UsernamePasswordToken(String username, char[] password, boolean rememberMe, String host) {this.rememberMe = false;this.username = username;this.password = password;this.rememberMe = rememberMe;this.host = host;}public UsernamePasswordToken(String username, String password, boolean rememberMe, String host) {this(username, password != null ? password.toCharArray() : null, rememberMe, host);}public String getUsername() {return this.username;}public void setUsername(String username) {this.username = username;}public char[] getPassword() {return this.password;}public void setPassword(char[] password) {this.password = password;}public Object getPrincipal() {return this.getUsername();}public Object getCredentials() {return this.getPassword();}public String getHost() {return this.host;}public void setHost(String host) {this.host = host;}public boolean isRememberMe() {return this.rememberMe;}public void setRememberMe(boolean rememberMe) {this.rememberMe = rememberMe;}public void clear() {this.username = null;this.host = null;this.rememberMe = false;if (this.password != null) {for(int i = 0; i < this.password.length; ++i) {this.password[i] = 0;}this.password = null;}}public String toString() {StringBuilder sb = new StringBuilder();sb.append(this.getClass().getName());sb.append(" - ");sb.append(this.username);sb.append(", rememberMe=").append(this.rememberMe);if (this.host != null) {sb.append(" (").append(this.host).append(")");}return sb.toString();}
}
(2) 认证流程

Shiro的认证流程如下:

  1. 用户提交身份认证请求,通常为登录操作
  2. Shiro将用户信息封装为Token
  3. Subject.login(token)方法调用,将Token传递给SecurityManager
  4. SecurityManager通过Realm查找用户信息并验证凭证
  5. 验证通过后,Shiro会将用户的信息存储到会话中
(3) 记住我VS认证
  • 认证:用户成功登录并创建会话,Session管理用户的登录状态
  • 记住我:用户选择"记住我"功能后,即使关闭浏览器,用户信息也能在下次访问时恢复,但不一定是完全的会话恢复。Shiro通过Cookie机制实现这一点
(4) 注销Logout

注销操作通过Subject.logout()方法实现。Shiro会自动清除Session,并将相关的登录信息从SecurityManager中移除

SecurityUtils.getSubject().logout();//shiro再注销一下
3. SpringBoot+Shiro认证

在SpringBoot项目中集成Shiro非常简单,只需进行少量配置即可实现认证功能

(1) 导入Shiro相关依赖
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>1.8.0</version>
</dependency>
(2) 自定义Realm

自定义Realm用于连接数据库进行身份认证和授权:

package com.ktjiaoyu.crm.config.shiro;import com.ktjiaoyu.crm.pojo.User;
import com.ktjiaoyu.crm.service.UserService;
import jakarta.annotation.Resource;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;/*** @Author: wangtao* @CreateTime: 2024-10-16-19:07* @Description: 自定义Realm* @Version: 1.0*/public class MyShiroRealm extends AuthorizingRealm {@Resourceprivate UserService userService;@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {System.out.println("调用MyShiroRealm.doGetAuthorizationInfo获取权限信息");//获取权限信息User user = (User) principalCollection.getPrimaryPrincipal();SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();//暂不授予权限信息,下章再搞授权return info;}@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {System.out.println("调用MyShiroRealm.doGetAuthorizationInfo获取身份信息!");//获取身份信息UsernamePasswordToken token =  (UsernamePasswordToken) authenticationToken;String usrName = token.getUsername();User user = userService.getUserByUsrName(usrName);if(user == null){throw new UnknownAccountException();//账号错误}if(user.getUsrFlag() == null || user.getUsrFlag().intValue() == 0){throw new LockedAccountException();//账号锁定}SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getUsrPassword(), getName());//返回身份信息return info;}
}
(3) 配置Shiro相关对象

在SpringBoot中配置Shiro,包含SecurityManager、过滤器和自定义Realm

package com.ktjiaoyu.crm.config.shiro;import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.util.ThreadContext;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** @Author: wangtao* @CreateTime: 2024-10-16-19:15* @Description: Shiro配置类* @Version: 1.0*/@Configuration
public class ShiroConfig {@Beanpublic MyShiroRealm myShiroRealm(){//自定义RealmMyShiroRealm myShiroRealm = new MyShiroRealm();return myShiroRealm;}@Beanpublic SecurityManager securityManager(){//安全管理器DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();ThreadContext.bind(securityManager);//加上这句代码手动绑定//注入RealmsecurityManager.setRealm(myShiroRealm());return securityManager;}@Beanpublic ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){//shiro过滤器:权限认证ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();//注入securityManagershiroFilterFactoryBean.setSecurityManager(securityManager);//权限验证:使用Filter控制资源(URL)的访问return shiroFilterFactoryBean;}
}
(4) 测试认证登录

配置好之后,可以通过以下方式测试登录功能:

//创建Realm(安全数据源)
IniRealm realm = new IniRealm("classpath:shiro.ini");
//通过shiro.ini配置文件 创建Realm
DefaultSecurityManager securityManager = new DefaultSecurityManager(realm);//注入创建的Realm(安全数据源)
securityManager.setRealm(realm);
SecurityUtils.setSecurityManager(securityManager);
//进行认证
Subject subject = SecurityUtils.getSubject();
//封装令牌
UsernamePasswordToken token = new UsernamePasswordToken("admin", "123456");
try {
subject.login(token);
}catch (AuthenticationException e){
e.printStackTrace();
}
System.out.println("是否认证通过:"+subject.isAuthenticated());
System.out.println("身份信息:"+subject.getPrincipal());

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

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

相关文章

【微服务】springboot远程docker进行debug调试使用详解

目录 一、前言 二、线上问题常用解决方案 2.1 微服务线上运行中常见的问题 2.2 微服务线上问题解决方案 2.3 远程debug概述 2.3.1 远程debug原理 2.3.2 远程debug优势 三、实验环境准备 3.1 搭建springboot工程 3.1.1 工程结构 3.1.2 引入基础依赖 3.1.3 添加配置文…

400行程序写一个实时操作系统(九):替换FreeRTOS的内存管理算法

前言 通过前面几章&#xff0c;笔者带领大家完成了内存管理算法的编写。 我们完成的内存管理算法&#xff0c;被称为小内存管理算法。我们也可以将它作为一个库&#xff0c;在后续的嵌入式开发中&#xff0c;使用我们自己编写的malloc&#xff0c;不仅效率会更高&#xff0c;…

机器学习笔记-2

文章目录 一、Linear model二、How to represent this function三、Function with unknown parameter四、ReLU总结、A fancy name 一、Linear model 线性模型过于简单&#xff0c;有很大限制&#xff0c;我们需要更多复杂模式 蓝色是线性模型&#xff0c;线性模型无法去表示…

如何匿名浏览网站,保护在线隐私?

在现如今的网络世界&#xff0c;在线隐私已不复存在。你总是被跟踪&#xff0c;即使你使用隐身模式也无济于事。隐身模式会阻止浏览器保存你的浏览历史记录。但它并不能阻止你的互联网服务提供商 (ISP)、雇主、学校、图书馆或你访问的网站看到你在网上做什么。 更有不法分子在未…

Lumerical学习——资源管理和运行模拟

一、资源管理&#xff08;Resource Manager&#xff09; 在模拟计算前必须对计算资源进行配置。采用资源管理器可以完成这项任务。单击主工具条的“资源&#xff08;Resources&#xff09;”按钮&#xff08;见上图&#xff09;就可以打开资源管理器。通常每个计算机只需设置一…

大型生物制药企业如何实现安全又高效地跨网域数据传输?

大型生物制药企业由于组织结构庞大、业务覆盖研发、生产及销售&#xff0c;因此内部会再细分为多个管理单位&#xff0c;包括研发部门、生产部门、质量控制部门、供应链管理部门及营销部和日常业务支撑部门等。在物理区域划分上&#xff0c;大型生物制药企业会设立实验室、研发…

摇人摇人, JD内推岗位(社招+校招)

摇人摇人, 有找工作的家人们看过来啊~ 虚位以待, 快到碗里来 算法开发工程师岗 京东云 北京|T7, 5-10年 岗位职责&#xff1a; 参与基于RAG知识库平台和ChatBI产品打造和商业化落地&#xff0c;进行相关技术&#xff1a;包括OCR、文档拆分、意图理解、多轮对话、NL2SQL、Embed…

mysql用户管理(user表列信息介绍,本质,管理操作),数据库的权限管理(权限列表,权限操作)

目录 用户管理 介绍 user表 介绍 列信息 Host User *_priv authentication_string 用户管理的本质 操作 创建用户 删除用户 修改用户信息 修改密码 自己修改 root用户修改指定用户的密码 数据库的权限 权限列表 给用户授权 查看权限 回收权限 刷新权限 …

Linux性能调优,还可以从这些方面入手

linux是目前最常用的操作系统&#xff0c;下面是一些常见的 Linux 系统调优技巧&#xff0c;在进行系统调优时&#xff0c;需要根据具体的系统负载和应用需求进行调整&#xff0c;并进行充分的测试和监控&#xff0c;以确保系统的稳定性和性能。同时&#xff0c;调优过程中要谨…

万界星空科技:智能称重打标系统

万界星空科技的称重系统是其为制造业&#xff0c;特别是线缆、漆包线、食品等行业提供的重要解决方案之一。以下是对该系统的详细介绍&#xff1a; 一、系统概述 万界星空科技称重系统是集成在其MES&#xff08;制造执行系统&#xff09;中的一个功能模块&#xff0c;专门用于…

基于springboot实习管理系统

作者&#xff1a;计算机学长阿伟 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、ElementUI等&#xff0c;“文末源码”。 系统展示 【2024最新】基于JavaSpringBootVueMySQL的&#xff0c;前后端分离。 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;…

React Agent 自定义实现

目录 背景 langchin 中的 agent langchin 中 agent 的问题 langchain 的 agent 案例 自定义 React Agent 大模型 工具定义 问题设定 问题改写&#xff0c;挖掘潜在意图 React Prompt 下一步规划 问题总结 代码 背景 之前使用过 langchian 中的 agent 去实现过一些…

2020年计算机网络408真题解析

第一题&#xff1a; 解析&#xff1a;OSI参考模型网络协议的三要素 网络协议的三要素&#xff1a;语法 &#xff0c;语义&#xff0c;同步&#xff08;时序&#xff09; 语法&#xff1a;定义收发双方所交换信息的格式 语法&#xff1a;定义收发双方所要完成的操作 网页的加载 …

深入理解队列(Queue)的实现(纯小白进)

目录&#xff1a; 前言一、 什么是队列?1.1、 队列的特性1.2、 队列的图解 二、 队列的详细实现2.1、 队列不同的实现方式2.2、 队列结构体2.3、 队列的初始化2.4、 入队列2.5、 出队列2.6、 获取对头元素2.7、 获取队尾元素2.8、 队列的判空2.9、 队列有效的元素个数2.10、 队…

Kind部署的K8s证书过期后的解决方案

证书通常有效期为1年&#xff0c;一年后服务将不可用解决方案就是更新证书 1. 找到 Kind 集群的控制平面容器名称,容器名称不一定是这个 docker ps --filter "namekind-control-plane"2. 进入 Kind 控制平面的容器&#xff1a; docker exec -it kind-control-plane…

洛谷入门刷题Day5(想刷水题结果被水题刷了)

P1304 哥德巴赫猜想 题目描述 输入一个偶数 N N N&#xff0c;验证 4 ∼ N 4\sim N 4∼N 所有偶数是否符合哥德巴赫猜想&#xff1a;任一大于 2 2 2 的偶数都可写成两个质数之和。如果一个数不止一种分法&#xff0c;则输出第一个加数相比其他分法最小的方案。例如 10 10…

论文笔记:Ontology-enhanced Prompt-tuning for Few-shot Learning

论文来源&#xff1a;WWW 2022 论文地址&#xff1a;https://arxiv.org/pdf/2201.11332.pdfhttps://arxiv.org/pdf/2201.11332.pdf 论文代码&#xff1a;暂未公开 笔记仅供参考&#xff0c;撰写不易&#xff0c;请勿恶意转载抄袭&#xff01; Abstract 小样本学习旨在基于…

Linux——传输层协议

目录 一再谈端口号 1端口号范围划分 2两个问题 3理解进程与端口号的关系 二UDP协议 1格式 2特点 3进一步理解 3.1关于UDP报头 3.2关于报文 4基于UDP的应用层协议 三TCP协议 1格式 2TCP基本通信 2.1关于可靠性 2.2TCP通信模式 3超时重传 4连接管理 4.1建立…

数据挖掘学习笔记:朴素贝叶斯 | Python复现

数据挖掘学习笔记&#xff1a;朴素贝叶斯 机器学习系列&#xff08;四&#xff09;&#xff1a;朴素贝叶斯&#xff08;华强买瓜版&#xff09; - yyxy的文章 - 知乎 十分钟&#xff0c;让你再也忘不掉贝叶斯分类 - VoidHaruhi的文章 - 知乎 《机器学习》&#xff08;西瓜书&am…

基于Arduino的简易收音机

DIY FM收音机&#xff1a;使用Arduino和Si4703模块打造 引言 在本项目中&#xff0c;我们将使用Arduino Nano和Si4703 FM调谐模块来构建一个功能完备的FM收音机接收器。这个易于跟随的指南非常适合想要深入无线电频率和无线通信世界的业余爱好者和电子爱好者。 Si4703模块是…