深入理解 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,一经查实,立即删除!

相关文章

Coturn 实战指南:WebRTC 中的 NAT 穿透利器

1. 什么是 Coturn&#xff1f; Coturn 是一种开源的 TURN(Traversal Using Relays around NAT)服务器&#xff0c;用于解决 NAT 穿透问题。它帮助客户端在受限网络环境(例如防火墙或 NAT 后面)中实现双向通信&#xff0c;常用于 WebRTC 应用、VoIP、在线游戏等场景。 2. Cotur…

React的局限性是什么?

性能&#xff1a; 虚拟 DOM 虽然提高了渲染性能&#xff0c;但在某些情况下可能会造成性能瓶颈&#xff0c;尤其是在处理大量数据或复杂更新时。对于非UI任务&#xff08;如计算密集型操作&#xff09;&#xff0c;React 本身并不擅长。 学习曲线&#xff1a; 对于初学者来说&a…

生信技能65 - SRA数据库公共数据自动化下载及SRA批量自动化拆分

根据NCBI Metadata数据表,实现SRA数据库公共数据自动化下载及SRA批量自动化拆分。 1. 程序逻辑 根据SraRunTable.csv自动从公共数据库下载SRA文件 ;模式0(默认)为下载模式,模式1为拆分模式,拆分支持进度显示;提取Metadata关键信息数据,重新写入新的文本文件。2. 运行示…

美化和定制你的Django Admin:使用SimpleUI

SimpleUI是一个简洁、美观的Django后台管理界面,它可以让你的Django Admin更加直观和易用。本文将指导你如何安装和配置SimpleUI,并进行自定义配置。 目录 安装Django创建Django项目创建Django app安装SimpleUI测试安装是否成功数据库迁移注册超级管理员登录验证自定义配置 …

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; …

datahub-postgres 连接

1、postgres 远程TCP/IP连接 1、修改postgres配置 /opt/homebrew/var/postgresql14/postgresql.conf #listen_addresses localhost, 127.0.0.1 # what IP address(es) to listen on;listen_addresses * # 增加这一条 2、修改/opt/homebrew/var/postgresql14/pg_hba.…

ElasticSearch 搜索、排序、分页功能

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

Unreal Engine 5 (UE5) 中“变换“(Transform)类型变量

在 Unreal Engine 5 (UE5) 中&#xff0c;"变换"&#xff08;Transform&#xff09;类型变量是一个非常常见和重要的数据类型&#xff0c;它用于表示 对象的位置&#xff08;Location&#xff09;、旋转&#xff08;Rotation&#xff09; 和 缩放&#xff08;Scale&a…

PyTorch 切片运算 (Slice Operator)

PyTorch 切片运算 {Slice Operator} 1. [:, -1, :]2. [:, [-1], :]References 1. [:, -1, :] https://github.com/karpathy/llama2.c/blob/master/model.py import torchlogits torch.arange(1, 16) print("logits.shape:", logits.shape) print("logits:\n&…

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的自由风格构建的项目,每个步骤…

CentOS 7.9 更换 YUM:解决宝塔安装困境的探索之旅

在进行网站搭建工作时&#xff0c;我满怀期待地准备安装宝塔面板&#xff0c;然而却遭遇了安装失败的挫折。经过一番排查与思考&#xff0c;我将目光聚焦到了系统的 YUM 上&#xff0c;怀疑它可能是导致问题的“罪魁祸首”。于是&#xff0c;我毅然决定对 CentOS 7.9 的 YUM 进…

如何解决垂直越权与水平越权问题

大家好&#xff0c;我是G探险者。 关于权限管理我们可能都了解过基于角色的访问控制RBAC技术。 但是关于水平越权和垂直越权的问题可能了解不多。 今天我们来聊聊垂直越权和水平越权的问题。 现在的Web应用和系统里&#xff0c;权限管理是确保数据安全和防止滥用的关键。垂直…

(SAST检测规则-8)连接字符串中的硬编码密码

严重等级&#xff1a;高危 缺陷详解&#xff1a; 在构建数据驱动的应用程序时&#xff0c;开发者通常需要通过数据库连接字符串与数据库进行交互。将敏感信息&#xff08;如密码、服务器IP地址或加密密钥&#xff09;硬编码在源代码中会带来以下风险&#xff1a; 信息暴露&a…

Spring Boot整合 RabbitMQ

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

Qwen 论文阅读记录

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

Python 元类(Meta Class):解密 Python 面向对象编程的幕后推手

在 Python 编程中&#xff0c;我们每天都在和类打交道&#xff0c;但是你是否也和我一样想过&#xff1a;类本身是什么&#xff1f;是谁创建了类&#xff1f;元类&#xff08;Meta Class&#xff09;就是用来创建类的"类"。今天让我们一起深入理解这个强大而神秘的特…

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;虽…