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

Apache Shiro 使用教程

Apache Shiro 使用教程

Apache Shiro是一个强大且灵活的开源安全框架,主要用于处理身份验证(Authentication)、授权(Authorization)、加密(Cryptography)和会话管理(Session Management)等安全相关的任务。它简化了在Java应用程序中集成安全功能的复杂性,广泛适用于各种类型的项目,如Web应用、命令行工具等。本教程将深入介绍Shiro的各个核心概念和功能,并通过一个基于Spring Boot的示例项目展示如何在项目中实际使用Shiro。

一、Shiro 核心概念

1.1 Subject

Subject是Shiro的核心概念,它代表一个实体,可以是用户、服务或其他任何需要与安全系统交互的主体。通过Subject,开发者可以执行认证、授权、会话管理等操作。例如,当用户登录系统时,实际上是通过Subject进行身份验证;当需要检查用户是否有权限执行某个操作时,也是通过Subject进行授权判断。

1.2 SecurityManager

SecurityManager是Shiro的安全管理中心,负责协调和管理所有的安全操作。它就像是一个大脑,接收来自Subject的请求(如登录、权限检查等),并委派相应的Realm去获取和处理安全数据。在一个应用程序中,通常只需要一个SecurityManager实例,它是整个Shiro安全体系的核心。

1.3 Realm

Realm是Shiro用于获取安全数据的组件,它定义了数据源的来源,比如数据库、LDAP(轻量级目录访问协议)、内存等。Realm负责从特定的数据源中读取用户信息、角色信息和权限信息等,以支持SecurityManager进行认证和授权操作。开发者需要根据实际需求实现自定义的Realm或者使用Shiro提供的默认Realm

二、Shiro 的核心功能

2.1 身份验证(Authentication)

身份验证是确认用户身份的过程,通常通过用户名和密码或其他凭证来完成。Shiro提供了简单的接口和方法,让开发者可以方便地实现身份验证逻辑。当用户提交登录请求时,Subject会调用login方法进行身份验证,SecurityManager会将验证请求委派给配置的RealmRealm根据用户提供的凭证在数据源中查找匹配的用户信息,如果找到且凭证验证通过,则身份验证成功;否则,抛出身份验证异常。

2.2 授权(Authorization)

授权是确定用户是否有权限访问特定资源或执行某个操作的过程。Shiro通过角色和权限的概念来实现授权管理。开发者可以为用户分配角色,为角色分配权限,然后在代码中通过SubjectisPermittedhasRole方法来检查用户是否具有相应的权限或角色。例如,在一个文件管理系统中,只有具有“管理员”角色的用户才有权删除文件,Shiro就可以通过授权机制来确保只有授权用户可以执行此操作。

2.3 加密(Cryptography)

Shiro提供了多种加密算法和工具,用于保护敏感信息,如用户密码的存储和加密传输等。例如,可以使用HashedCredentialsMatcher来对用户密码进行哈希加密存储,防止密码泄露后被直接获取。Shiro还支持对称加密和非对称加密算法,满足不同场景下的加密需求。

2.4 会话管理(Session Management)

Shiro提供了会话管理功能,用于跟踪和管理用户的会话状态。在一个Web应用中,用户的会话状态可以包含用户的登录状态、登录时间、最近访问的页面等信息。Shiro的会话管理机制允许开发者在不同的应用服务器和分布式环境中轻松地管理用户会话,并且提供了会话监听器、会话过期处理等功能,方便开发者进行定制和扩展。

三、基于Spring Boot集成Shiro的示例

3.1 创建Spring Boot项目

首先,创建一个基于Spring Boot的Web应用项目。可以使用Spring Initializr(https://start.spring.io/ )工具快速创建项目,选择以下依赖:
• Spring Web
• Spring Boot DevTools(可选,用于开发时的热部署和快速重启)

3.2 添加Shiro依赖

在项目的pom.xml文件中添加Shiro和Shiro与Spring集成的依赖:

<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring-boot-web-starter</artifactId><version>1.9.1</version>
</dependency>

3.3 配置Shiro

创建一个配置类ShiroConfig,用于配置Shiro的核心组件,包括SecurityManagerRealm和过滤器链等:

import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class ShiroConfig {@Beanpublic Realm realm() {// 这里可以创建自定义Realm或使用Shiro提供的默认Realmreturn new CustomRealm();}@Beanpublic DefaultWebSecurityManager securityManager() {DefaultWebSecurityManager manager = new DefaultWebSecurityManager();manager.setRealm(realm());return manager;}@Beanpublic ShiroFilterChainDefinition shiroFilterChainDefinition() {DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();// 配置路径的访问权限,anon表示无需认证,authc表示需要认证chainDefinition.addPathDefinition("/login", "anon");chainDefinition.addPathDefinition("/logout", "logout");chainDefinition.addPathDefinition("/**", "authc");return chainDefinition;}
}

3.4 自定义Realm

创建一个自定义的RealmCustomRealm,用于从数据库或其他数据源中获取用户信息和权限信息:

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;import java.util.HashSet;
import java.util.Set;public class CustomRealm extends AuthorizingRealm {// 用户认证@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {UsernamePasswordToken upToken = (UsernamePasswordToken) token;String username = upToken.getUsername();// 模拟从数据库中获取用户信息if (!"admin".equals(username) &&!"user".equals(username)) {throw new UnknownAccountException("用户不存在");}String password = "123456"; // 实际应用中应从数据库获取真实的用户密码return new SimpleAuthenticationInfo(username, password, getName());}// 用户授权@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {String username = (String) principals.getPrimaryPrincipal();SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();// 模拟从数据库中获取用户角色和权限if ("admin".equals(username)) {authorizationInfo.addRole("admin");authorizationInfo.addStringPermission("user:delete");} else if ("user".equals(username)) {authorizationInfo.addRole("user");authorizationInfo.addStringPermission("user:view");}return authorizationInfo;}
}

3.5 编写控制器

创建一个控制器类ShiroController,用于处理登录、访问受保护资源等请求:

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
public class ShiroController {@GetMapping("/login")public String loginPage() {return "登录页面";}@PostMapping("/login")public String login(@RequestParam String username, @RequestParam String password) {Subject subject = SecurityUtils.getSubject();UsernamePasswordToken token = new UsernamePasswordToken(username, password);try {subject.login(token);return "登录成功";} catch (AuthenticationException e) {return "登录失败: " + e.getMessage();}}@GetMapping("/logout")public String logout() {SecurityUtils.getSubject().logout();return "已登出";}@GetMapping("/protected")public String protectedResource() {Subject subject = SecurityUtils.getSubject();if (subject.isAuthenticated()) {return "访问受保护资源成功";} else {return "请先登录";}}
}

3.6 测试应用

启动Spring Boot应用程序,访问http://localhost:8080/login ,可以看到登录页面。通过表单或发送POST请求(http://localhost:8080/login?username=admin&password=123456 )进行登录。登录成功后,可以访问受保护的资源http://localhost:8080/protected ,如果未登录则会被拦截并重定向到登录页面。同时,可以访问http://localhost:8080/logout 来登出当前用户。

四、总结

本教程介绍了Apache Shiro的核心概念和主要功能,包括身份验证、授权、加密和会话管理。通过一个基于Spring Boot的示例项目,展示了如何配置和使用Shiro来实现简单的安全控制。在实际项目中,你可以根据需求进一步扩展和定制Shiro的功能,如集成数据库、实现更复杂的权限管理逻辑等。Shiro作为一个成熟且强大的安全框架,能够大大简化Java应用程序中的安全开发工作,提高应用程序的安全性和可靠性。

相关文章:

Apache Shiro 使用教程

Apache Shiro 使用教程 Apache Shiro是一个强大且灵活的开源安全框架&#xff0c;主要用于处理身份验证&#xff08;Authentication&#xff09;、授权&#xff08;Authorization&#xff09;、加密&#xff08;Cryptography&#xff09;和会话管理&#xff08;Session Manage…...

用maven生成springboot多模块项目

用Maven生成Spring Boot多模块项目&#xff0c;可以按照以下步骤操作&#xff1a; 1. 创建父项目 首先&#xff0c;使用Maven的archetype插件创建一个空的Maven项目作为父项目。打开终端&#xff0c;执行以下命令&#xff1a; mvn archetype:generate -DgroupIdcom.example -…...

【最佳实践】Go 状态模式

设计思路 状态模式的核心在于将对象的行为封装在特定的状态类中&#xff0c;使得对象在不同的状态下表现出不同的行为。每个状态实现同一个接口&#xff0c;允许对象在运行时通过改变其内部状态对象来改变其行为。状态模式使得状态转换更加明确&#xff0c;并且易于扩展新的状…...

智慧社区3.0

项目介绍&#xff1a; 此项目旨在推动成都市探索**超大城市社区发展治理新路**&#xff0c;由三个实验室负责三大内容 1、**研发社区阵地空间管理模块**&#xff1a;AI算法实现态势感知&#xff08;如通过社区图片和视频、文本&#xff0c;对环境 空间质量、绿视率、安全感分…...

C#语法基础总结

输入和输出 输入 Console.Read(); 从屏幕读取一个字符&#xff0c;并返回该字符所对应的整型数字 Console.ReadLine(); 从屏幕读取一串字符&#xff0c;并返回该字符串 输出 Console.WriteLine(); 输出内容&#xff0c;并换行 Console.Write(); 输出内容&#xff0c;不换行…...

Springboot+Vue登录、注册功能(含验证码)(后端!)

我们首先写一个接口&#xff0c;叫login&#xff01;然后对传入一个user&#xff0c;因为我们前端肯定是要传过来一个user&#xff0c;然后我们后端返回一个user&#xff0c;因为我们要根据这个去校验&#xff01;我们还引入了一个hutool的一个东西&#xff0c;在pom文件里面引…...

深入理解 HTML 中的<div>和元素:构建网页结构与样式的基石

一、引言 在 HTML 的世界里&#xff0c;<div>和元素虽看似普通&#xff0c;却扮演着极为关键的角色。它们就像网页搭建过程中的万能积木&#xff0c;能够将各种 HTML 元素巧妙地组合起来&#xff0c;无论是构建页面布局&#xff0c;还是对局部内容进行样式调整&#xff…...

搞定python之八----操作mysql

本文是《搞定python》系列文章的第八篇&#xff0c;讲述利用python操作mysql数据库。相对来说&#xff0c;本文的综合性比较强&#xff0c;包含了操作数据库、异常处理、元组等内容&#xff0c;需要结合前面的知识点。 1、安装mysql模块 PyMySql模块相当于数据库的驱动&#…...

游戏立项时期随笔记录(1)

模拟经营的项目还没有完全结束&#xff0c;这几天又有可能涉及到一个新项目。感想随笔记录一下&#xff0c;防止忘记。今天一天整理这个&#xff0c;搞得今天没时间看数学和AI。 在 Unity3D 游戏前端主程序的立项时期&#xff0c;核心目标是明确技术方向、评估可行性、搭建基础…...

LVGL 中设置 UI 层局部透明,显示下方视频层

LVGL层次 LVGL自上而下分别是layer_sys > layer_top > lv_sreen_active > layer_bottom 即 系统层、顶层、活动屏幕、底层 原理 如果将UI设置为局部透明&#xff0c;显示下方的视频层&#xff0c;不仅仅需要将当前活动屏幕的背景设置为透明&#xff0c;还需要将底层…...

Debezium日常分享系列之:Debezium 3.1.0.Beta1发布

Debezium日常分享系列之&#xff1a;Debezium 3.1.0.Beta1发布 新特性和改进Debezium 平台的首次发布Percona 的最小锁定新的 Oracle 源信息 SCN 和时间戳字段Vitess Epoch/零日期列解析的变化Vitess 二进制排序的 tiny、medium 和 long 文本列的变化CloudEvent traceparent 支…...

21.多态

一、多态概念 多种形态。 静态多态&#xff1a;编译时多态。&#xff08;函数重载&#xff09; 动态多态&#xff1a;运行时多态。&#xff08;继承关系下&#xff0c;调用父类指针或引用&#xff0c;对于不同的对象有不同的行为&#xff09; 二、多态的定义及实现 1&#xff…...

【蓝桥杯】第十三届C++B组省赛

⭐️个人主页&#xff1a;小羊 ⭐️所属专栏&#xff1a;蓝桥杯 很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~ 目录 试题A&#xff1a;九进制转十进制试题B&#xff1a;顺子日期试题C&#xff1a;刷题统计试题D&#xff1a;修剪灌木试题E&#xf…...

C# PaddleOCR字符识别

1 安装Nuget 2 C# using System; using OpenCvSharp; using Sdcb.PaddleOCR; using Sdcb.PaddleOCR.Models.Local; using Sdcb.PaddleOCR.Models; using Sdcb.PaddleInference;namespace ConsoleApp1 {public class MichaelOCR{string imagePath "D:\\BUFFER\\VS\\Text\…...

网络爬虫相关

一、爬虫的基础内容 1、基本概念和用途 1.1、概念&#xff1a; 模拟浏览器、发送请求&#xff0c;获取响应。&#xff08;只能获取客户端所展示出来的数据&#xff09; 1.2、特点&#xff1a;知识碎片化&#xff0c;针对不同的网站对应的方法也不同。 爬虫&#xff1a;模拟…...

算法及数据结构系列 - 二分查找

系列文章目录 算法及数据结构系列 - BFS算法 文章目录 二分查找框架思路经典题型二分查找寻找左侧边界寻找右侧边界 刷题875. 爱吃香蕉的珂珂1011. 在 D 天内送达包裹的能力392. 判断子序列 二分查找 框架思路 int binarySearch(int[] nums, int target) {int left 0, righ…...

多环境开发-Profiles

在实际的项目开发中&#xff0c;我们通常会涉及多个环境&#xff0c;如开发环境&#xff08;dev&#xff09;、测试环境&#xff08;test&#xff09;和生产环境&#xff08;pro&#xff09;。在不同的环境下&#xff0c;程序的配置信息会有所不同&#xff0c;例如连接的数据库…...

《TCP/IP网络编程》学习笔记 | Chapter 18:多线程服务器端的实现

《TCP/IP网络编程》学习笔记 | Chapter 18&#xff1a;多线程服务器端的实现 《TCP/IP网络编程》学习笔记 | Chapter 18&#xff1a;多线程服务器端的实现线程的概念引入线程的背景线程与进程的区别 线程创建与运行pthread_createpthread_join可在临界区内调用的函数工作&#…...

MambaVision:一种Mamba-Transformer混合视觉骨干网络

摘要 我们提出了一种新型混合Mamba-Transformer主干网络&#xff0c;称为MambaVision&#xff0c;该网络专为视觉应用而设计。我们的核心贡献包括重新设计Mamba公式&#xff0c;以增强其对视觉特征的高效建模能力。此外&#xff0c;我们还对将视觉Transformer&#xff08;ViT&…...

【Visio使用教程】

Visio使用教程 1. Visio 的基本介绍1.1 Visio 是什么&#xff1f;核心特点&#xff1a; 1.2 主要功能与应用场景典型用途&#xff1a;行业应用&#xff1a; 1.3 版本与兼容性1.4 Visio下载1.5 安装 2. Visio 的界面与基础操作2.1 界面布局详解2.2 创建新文档与模板选择2.3 形状…...

深度学习-服务器训练SparseDrive过程记录

1、cuda安装 1.1 卸载安装失败的cuda 参考&#xff1a;https://blog.csdn.net/weixin_40826634/article/details/127493809 注意&#xff1a;因为/usr/local/cuda-xx.x/bin/下没有卸载脚本&#xff0c;很可能是apt安装的&#xff0c;所以通过执行下面的命令删除&#xff1a; a…...

什么是梯度方差和缩放因子

什么是梯度方差和缩放因子 目录 什么是梯度方差和缩放因子计算梯度方差(Fisher 信息)作用梯度方差计算方式(方差越大,参数越重要,小步更新(细致一些))示例使用缩放因子作用示例两者的区别总结在 LoRA(Low-Rank Adaptation)中,计算梯度方差和使用缩放因子是两个不同的概…...

Linux 如何上传本地文件以及下载文件到本地命令总结

如果你希望在 Shell 终端中将远程服务器上的文件下载到本地电脑&#xff0c;可以使用以下工具和命令&#xff1a; 1. rz / sz&#xff08;用于 Xshell、MobaXterm 等终端&#xff09; 如果你使用的是Xshell、SecureCRT、MobaXterm等支持 rz/sz 的终端&#xff0c;可以使用 rz …...

学习单片机需要多长时间才能进行简单的项目开发?

之前有老铁问我&#xff0c;学单片机到底要多久&#xff0c;才能进行简单的项目开发&#xff1f;是三个月速成&#xff0c;还是三年磨一剑&#xff1f; 今天咱们就来聊聊这个话题&#xff0c;我不是什么高高在上的专家&#xff0c;就是个踩过无数坑、烧过几块板子的“技术老友”…...

stm32 L432KC(mbed)入门第一课

目录 一. 前言 二. 专栏意义 三. MS入门第一课 一. 前言 新的一年MS课程又开始了&#xff0c;同时也到了该专栏的第三个年头。在前两年中&#xff0c;该专栏帮助了很多第一次接触单片机的同学。其中&#xff0c;有的同学订阅专栏是为了更好的完成并且通过MS这门课程&#xf…...

【面试手撕】非常规算法,多线程常见手撕题目

【面试手撕】非常规算法&#xff0c;多线程常见手撕题目 生产者消费者ReentrantLock实现的生产苹果/消费苹果synchronized实现的生产消费LinkedBlockingQueue阻塞队列方法实现多条件资源分配分布式任务调度模拟 交替打印两个线程交替打印1-100之间的数ReentrantLock 实现synchr…...

Python 基础语法详解

一、变量和数据类型 变量 在 Python 中&#xff0c;变量无需声明类型&#xff0c;直接赋值即可。变量名区分大小写。 # 整数类型 age 25 print(age) # 输出&#xff1a;25# 浮点数类型 height 1.75 print(height) # 输出&#xff1a;1.75# 字符串类型 name "张三&…...

批量给 Excel 添加或删除密码保护|Excel 批量设置打开密码和只读密码

我们在将 Excel 文档发送给第三方或者进行存档的时候&#xff0c;对 Excel 文档添加密码保护是非常重要的一个操作。添加保护后的 Excel 文档。就只能有相应权限的用户才能够打开或者编辑操作。尤其是当我们 Excel 文档中内容非常敏感非常重要的时候&#xff0c;添加保护就显得…...

4.JVM-垃圾回收介绍

记录个人学习中记录笔记&#xff0c;如有错误请您指正&#xff0c;谢谢&#x1f64f; 垃圾回收器发展史 传统垃圾回收: 分代回收 不同代有不同的垃圾回收机制 保底 标记清除算法 垃圾识别算法 引用计数法 缺陷:下图2 出现循环引用 无法解决 可达性分析 大部分(Java,pytho…...

Redis-锁-商品秒杀防止超卖

一、秒杀&#xff08;Seckill&#xff09;​ 1. ​定义 ​秒杀&#xff1a;短时间内&#xff08;如1秒内&#xff09;大量用户同时抢购 ​限量低价商品 的营销活动。​典型场景&#xff1a;双11热门商品抢购、小米手机首发、演唱会门票开售。 2. ​技术挑战 挑战点说明后果…...