深入理解 Apache Shiro:安全框架全解析

 亲爱的小伙伴们😘,在求知的漫漫旅途中,若你对深度学习的奥秘、JAVA 、PYTHON与SAP 的奇妙世界,亦或是读研论文的撰写攻略有所探寻🧐,那不妨给我一个小小的关注吧🥰。我会精心筹备,在未来的日子里不定期地为大家呈上这些领域的知识宝藏与实用经验分享🎁。每一个点赞👍,都如同春日里的一缕阳光,给予我满满的动力与温暖,让我们在学习成长的道路上相伴而行,共同进步✨。期待你的关注与点赞哟🤗!

一、引言

在当今的软件开发领域,安全是至关重要的一环。无论是企业级应用还是普通的移动应用,都需要保护用户数据和系统资源免受非法访问。Apache Shiro 作为一款强大的 Java 安全框架,提供了全面的安全解决方案,涵盖了身份验证、授权、加密和会话管理等多个方面。在这篇博客中,我们将深入探讨 Shiro 的核心概念、架构以及如何在实际项目中应用它来构建安全的系统。

二、Shiro 核心概念

(一)Subject

Subject 是 Shiro 安全框架的核心概念之一,它代表了当前与系统进行交互的用户或实体。可以将其看作是一个安全上下文的持有者,通过它可以进行身份验证、授权、获取会话等操作。例如,在一个 Web 应用中,当一个用户发起请求时,Shiro 会创建一个对应的 Subject 对象来代表这个用户。

以下是一个简单的代码示例,展示如何获取当前的 Subject:

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;public class ShiroExample {public static void main(String[] args) {// 获取当前 SubjectSubject currentUser = SecurityUtils.getSubject();System.out.println("当前 Subject: " + currentUser);}
}

(二)SecurityManager

SecurityManager 是 Shiro 的核心组件,它负责协调和管理整个安全系统。它是 Shiro 架构的核心枢纽,所有的安全操作都通过它来进行调度和执行。它管理着所有的 Subject、Realm 以及其他安全组件之间的交互。

在 Shiro 的配置中,通常需要创建并配置一个 SecurityManager 实例。例如,在一个基于 Spring 的应用中,可以这样配置:

<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"><property name="realm" ref="userRealm"/>
</bean>

这里的 userRealm 是一个自定义的 Realm,用于处理身份验证和授权信息。

(三)Realm

Realm 是 Shiro 进行身份验证和授权的数据源。它负责从数据库、文件系统或其他存储介质中获取用户的身份信息(如用户名、密码)和授权信息(如角色、权限)。可以将 Realm 看作是 Shiro 与实际数据存储之间的桥梁。

例如,我们可以创建一个简单的 Realm 来从内存中获取用户信息:

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;import java.util.HashMap;
import java.util.Map;public class SimpleRealm extends AuthorizingRealm {private Map<String, String> userMap = new HashMap<>();public SimpleRealm() {userMap.put("user1", "password1");userMap.put("user2", "password2");}@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {// 这里可以根据用户信息加载对应的角色和权限信息,暂时为空实现return null;}@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {String username = (String) token.getPrincipal();String password = userMap.get(username);if (password!= null) {return new SimpleAuthenticationInfo(username, password, getName());} else {throw new AuthenticationException("用户不存在");}}
}

三、Shiro 架构

Shiro 的架构设计非常灵活和可扩展,主要由以下几个核心组件组成(如图 1 所示):

  • Subject:如前所述,代表当前用户或实体。
  • SecurityManager:整个安全系统的核心管理者。
  • Realm:数据源,提供身份验证和授权数据。
  • Authenticator:负责处理身份验证逻辑,它会调用 Realm 来获取用户信息并进行验证。
  • Authorizer:负责处理授权逻辑,根据用户的角色和权限信息来决定是否允许访问特定资源。
  • SessionManager:管理用户会话,包括会话的创建、销毁、超时设置等。

当一个 Subject 发起一个安全操作(如访问受保护资源)时,请求会被传递到 SecurityManager。SecurityManager 首先会调用 Authenticator 进行身份验证,如果身份验证成功,再调用 Authorizer 进行授权检查。如果授权通过,Subject 就可以访问相应的资源。

四、身份验证

(一)身份验证流程

身份验证是确定用户身份的过程。在 Shiro 中,通常使用用户名和密码进行身份验证。其基本流程如下:

  1. 创建一个 UsernamePasswordToken,包含用户名和密码信息。
  2. 获取当前的 Subject。
  3. 通过 Subject 的 login 方法传入 UsernamePasswordToken 进行身份验证。

以下是代码示例:

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;public class AuthenticationExample {public static void main(String[] args) {Subject currentUser = SecurityUtils.getSubject();// 创建用户名密码令牌UsernamePasswordToken token = new UsernamePasswordToken("user1", "password1");try {// 进行身份验证currentUser.login(token);System.out.println("身份验证成功");} catch (Exception e) {System.out.println("身份验证失败: " + e.getMessage());}}
}

(二)自定义身份验证策略

Shiro 允许我们自定义身份验证策略,以满足不同的业务需求。例如,我们可以实现一个多 Realm 身份验证策略,当多个 Realm 存在时,根据不同的规则来确定身份验证是否成功。

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
import org.apache.shiro.realm.Realm;import java.util.ArrayList;
import java.util.Collection;public class MyModularRealmAuthenticator extends ModularRealmAuthenticator {@Overrideprotected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws AuthenticationException {// 获取所有的 RealmCollection<Realm> realms = getRealms();if (realms == null || realms.isEmpty()) {throw new AuthenticationException("没有配置 Realm");}ArrayList<AuthenticationInfo> infoList = new ArrayList<>();for (Realm realm : realms) {// 每个 Realm 进行身份验证AuthenticationInfo info = realm.getAuthenticationInfo(authenticationToken);if (info!= null) {infoList.add(info);}}if (infoList.isEmpty()) {throw new AuthenticationException("身份验证失败");} else if (infoList.size() == 1) {return infoList.get(0);} else {// 自定义多 Realm 身份验证成功的逻辑,这里简单返回第一个return infoList.get(0);}}
}

五、授权

(一)基于角色的授权

Shiro 支持基于角色的授权,即根据用户所属的角色来决定是否允许访问资源。首先需要在 Realm 中加载用户的角色信息,然后在代码中通过 hasRole 等方法进行授权检查。

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;public class AuthorizationExample {public static void main(String[] args) {Subject currentUser = SecurityUtils.getSubject();if (currentUser.hasRole("admin")) {System.out.println("用户具有管理员角色,可以访问特定资源");} else {System.out.println("用户没有管理员角色,无权访问");}}
}

(二)基于权限的授权

除了基于角色,Shiro 还支持基于权限的授权,更加细粒度地控制资源访问。权限可以是对某个操作或资源的特定许可。

例如,在 Realm 中加载用户的权限信息后,可以这样进行授权检查:

if (currentUser.isPermitted("user:create")) {System.out.println("用户有权创建用户");
} else {System.out.println("用户无权创建用户");
}

六、会话管理

Shiro 提供了强大的会话管理功能,可以管理用户的会话状态,包括会话的创建、销毁、超时设置等。

在 Web 应用中,可以通过配置 SessionManager 来定制会话管理策略。例如:

<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"><property name="globalSessionTimeout" value="1800000"/> <!-- 会话超时时间,单位毫秒 -->
</bean>

在代码中,可以通过 Subject 获取会话对象并进行操作:

Subject currentUser = SecurityUtils.getSubject();
// 获取会话
org.apache.shiro.session.Session session = currentUser.getSession();
session.setAttribute("userData", "一些用户数据");
String data = (String) session.getAttribute("userData");
System.out.println("会话中的数据: " + data);

七、加密

Shiro 提供了方便的加密工具,用于对敏感数据(如密码)进行加密存储和传输。

例如,使用 Shiro 的 Md5Hash 对密码进行加密:

import org.apache.shiro.crypto.hash.Md5Hash;public class EncryptionExample {public static void main(String[] args) {String password = "password1";// 使用 Md5 加密密码,可指定盐值Md5Hash md5Hash = new Md5Hash(password, "salt");System.out.println("加密后的密码: " + md5Hash.toHex());}
}

八、总结

Apache Shiro 是一款功能强大、灵活且易于使用的 Java 安全框架。通过深入理解其核心概念(如 Subject、SecurityManager、Realm)、架构以及身份验证、授权、会话管理和加密等关键功能,我们可以在实际项目中有效地构建安全可靠的系统。无论是简单的单体应用还是复杂的分布式系统,Shiro 都能提供合适的安全解决方案,帮助我们保护用户数据和系统资源免受各种安全威胁。在后续的开发中,我们可以根据具体的业务需求进一步探索 Shiro 的高级特性和定制化配置,以构建更加完善的安全体系。

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

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

相关文章

python学习笔记—7—变量拼接

1. 字符串的拼接 print(var_1 var_2) print("supercarry" "doinb") name "doinb" sex "man" score "100" print("sex:" sex " name:" name " score:" score) 注意&#xff1a; …

ElasticSearch 搜索、排序、分页功能

一、DSL 查询文档 ElasticSearch 的查询依然是基于 json 风格的 DSL 来实现的。 官方文档&#xff1a;https://www.elastic.co/guide/en/elasticsearch/reference/8.15/query-dsl.html 1.1 DSL 查询分类 常见的查询类型包括&#xff1a; 查询所有&#xff1a;查询出所有数…

2025系统架构师(一考就过):选择题基础知识二

考点14&#xff1a;知识产权和标准化 真题1&#xff1a;甲软件公司受乙企业委托安排公司软件设计师开发了信息系统管理软件&#xff0c;由于在委托开发合同中未对软件著作权归属作出明确的约定&#xff0c;所以该信息系统管理软件的著作权由(甲) 享有。 真题2&#xff1a;根据…

【ubuntu18.04】ubuntu18.04安装EasyCwmp操作说明

参考链接 Tutorial – EasyCwmphttps://easycwmp.org/tutorial/ EasyCwmp 介绍 EasyCwmp 设计包括 2 个部分&#xff1a; EasyCwmp 核心&#xff1a;它包括 TR069 CWMP 引擎&#xff0c;负责与 ACS 服务器的通信。它是用 C 语言开发的。EasyCwmp DataModel&#xff1a;它包…

Jenkins流水线初体验(六)

DevOps之安装和配置 Jenkins (一) DevOps 之 CI/CD入门操作 (二) Sonar Qube介绍和安装(三) Harbor镜像仓库介绍&安装 (四) Jenkins容器使用宿主机Docker(五) Jenkins流水线初体验(六) 一、Jenkins流水线任务介绍 之前采用Jenkins的自由风格构建的项目,每个步骤…

Spring Boot整合 RabbitMQ

文章目录 一. 引入依赖二. 添加配置三. Work Queue(工作队列模式)声明队列生产者消费者 四. Publish/Subscribe(发布订阅模式)声明队列和交换机生产者消费者 五. Routing(路由模式)声明队列和交换机生产者消费者 六. Topics(通配符模式)声明队列和交换机生产者消费者 一. 引入依…

Qwen 论文阅读记录

本文仅作自己初步熟悉大模型&#xff0c;梳理之用&#xff0c;慢慢会更改/增加/删除&#xff0c;部分细节尚未解释&#xff0c;希望不断学习之后&#xff0c;能够完善补充。若有同道之人&#xff0c;欢迎指正探讨。 关于后面的code-qwen and math-qwen&#xff0c;我个人认为依…

JCR一区牛顿-拉夫逊优化算法+分解对比!VMD-NRBO-Transformer-BiLSTM多变量时序光伏功率预测

JCR一区牛顿-拉夫逊优化算法分解对比&#xff01;VMD-NRBO-Transformer-BiLSTM多变量时序光伏功率预测 目录 JCR一区牛顿-拉夫逊优化算法分解对比&#xff01;VMD-NRBO-Transformer-BiLSTM多变量时序光伏功率预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.中科院…

如何在小米平板5上运行 deepin 23 ?

deepin 23 加入了 ARM64 支持&#xff0c;这里尝试将 deepin 系统刷入平板中&#xff0c;平常使用中&#xff0c;带个笔记本电脑有时候也会嫌比较麻烦&#xff0c;把 Linux 系统刷入平板中既满足了使用需要&#xff0c;又满足了轻便的需求。为什么不使用 Termux &#xff1f;虽…

QT6 Socket通讯封装(TCP/UDP)

为大家分享一下最近封装的以太网socket通讯接口 效果演示 如图&#xff0c;界面还没优化&#xff0c;后续更新 废话不多说直接上教程 添加库 如果为qmake项目中&#xff0c;在.pro文件添加 QT network QT core gui QT networkgreaterThan(QT_MAJOR_VERS…

all/any函数可以对“条件”打包(Python)

操作符直观易读适用简单逻辑&#xff0c;函数紧凑好写便于多条件处理。 (笔记模板由python脚本于2024年12月12日 22:19:10创建&#xff0c;本篇笔记适合有一定编程基础的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&#xff…

js:v-for循环中我希望再次循环七张图片,需要在v-for中嵌套一个v-for还是?

问&#xff1a; div classxxxx v-for(item,index) in data :keyindex div classimgDiv div classimgDivBox /div /div .imgDivBox { .background-img(/assets/images/top_01.png) } 这是现在设置的图片&#xff0c;但是现在我希望遍历一个数组然后遍历top01-top07&…

黑皮书-计算机科学导论02

目录 第二部分&#xff1a;计算机硬件 第5章计算机组成 5.1中央处理单元 Ⅰ.算数逻辑单元 Ⅱ.控制单元 Ⅲ.寄存器 5.2主存储器 Ⅰ.随机存取存储器(RAM) Ⅱ.只读存储器(ROM) 高速缓冲存储器(Cache) 5.3输入/输出子系统 Ⅰ.非存储设备 Ⅱ.存储设备&#xff08;辅助存…

小程序开发中的插件生态与应用-上

更多精彩内容都在公zhong号&#xff1a;小白的大数据之旅 在小程序的开发过程中&#xff0c;插件作为扩展功能、提升效率的重要工具&#xff0c;扮演着不可或缺的角色。它们不仅能够帮助开发者快速集成复杂的功能模块&#xff0c;还能优化开发流程&#xff0c;缩短项目周期。 …

优选算法——分治(快排)

1. 颜色分类 题目链接&#xff1a;75. 颜色分类 - 力扣&#xff08;LeetCode&#xff09; 题目展示&#xff1a; 题目分析&#xff1a;本题其实就要将数组最终分成3块儿&#xff0c;这也是后面快排的优化思路&#xff0c;具体大家来看下图。 这里我们上来先定义了3个指针&…

【大模型系列篇】GPU资源容器化访问使用指南

在当今的高性能计算和机器学习领域&#xff0c;GPU&#xff08;图形处理单元&#xff09;因其卓越的并行计算能力而扮演着至关重要的角色。随着容器化技术如 Docker 的普及&#xff0c;越来越多的数据科学家和开发者选择将他们的应用和工作负载封装到 Docker 容器中&#xff0c…

【毕业设计选题】数据科学与大数据专业毕业设计选题与建议

目录 前言 毕设选题 开题指导建议 更多精选选题 选题帮助 最后 前言 大家好,这里是海浪学长毕设专题! 大四是整个大学期间最忙碌的时光&#xff0c;一边要忙着准备考研、考公、考教资或者实习为毕业后面临的升学就业做准备,一边要为毕业设计耗费大量精力。学长给大家整…

大数据笔记之flink-cdc实时同步数据

大数据笔记之flink-cdc实时同步数据(mysql -->doris) 一、基本概念 Flink CDC 是一个基于流的数据集成工具&#xff0c;旨在为用户提供一套功能更加全面的编程接口&#xff08;API&#xff09;。 该工具使得用户能够以 YAML配置文件的形式&#xff0c;优雅地定义其 ETL&…

蓝桥杯新年题解 | 第15届蓝桥杯迎新篇

蓝桥杯新年题解 | 第15届蓝桥杯迎新篇 2024年的蓝桥杯即将拉开序幕&#xff01;对于许多编程爱好者来说&#xff0c;这不仅是一次展示自我能力的舞台&#xff0c;更是一次学习和成长的机会。作为一名大一新生的小蓝&#xff0c;对蓝桥杯充满了期待&#xff0c;但面对初次参赛的…

【有啥问啥】大语言模型Prompt中的“System指令”:深入剖析与误区澄清

大语言模型Prompt中的“System指令”&#xff1a;深入剖析与误区澄清 引言 在与大语言模型&#xff08;LLM&#xff09;交互时&#xff0c;“prompt”&#xff08;提示符&#xff09;这一概念已不再陌生。Prompt是引导模型生成特定类型文本的关键输入&#xff0c;决定了模型的…