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

news2025/2/27 5:30:11

 亲爱的小伙伴们😘,在求知的漫漫旅途中,若你对深度学习的奥秘、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) {
        // 获取当前 Subject
        Subject 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");
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        // 这里可以根据用户信息加载对应的角色和权限信息,暂时为空实现
        return null;
    }

    @Override
    protected 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 {

    @Override
    protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws AuthenticationException {
        // 获取所有的 Realm
        Collection<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.coloradmin.cn/o/2258125.html

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

相关文章

《大宋豪侠传》客户端源码 + 服务端源码 + 工具源码 + 资源,大小16.3G

《大宋豪侠传》客户端源码 服务端源码 工具源码 资源&#xff0c;大小16.3G 下载地址&#xff1a; 通过网盘分享的文件&#xff1a;【源码】《大宋豪侠传》客户端源码 服务端源码 工具源码 资源&#xff0c;大小16.3G 链接: https://pan.baidu.com/s/1lUf84LzXKB3iM7L-1P…

linux学习笔记01 基础命令

目录 创建 touch 创建文件 &#xff08;创建但是不打开&#xff09; vi / vim 创建文件 (创建一个文件并打开) mkdir 创建文件夹 切换目录 cd 查看 pwd 查看当前目录完整路径 ls 查看目录信息 dir 查看目录信息 ll 表示查看目标目录下的信息 ls -a 查看当前目录下的…

MVC基础——市场管理系统(三)Clean Architecture

文章目录 项目地址五、Clean Architecture5.1 user cage driven5.1.1创建CoreBusiness 5.2 创建UseCases5.2.1 创建CategoriesUseCases1. 创建VeiwCategoriesUseCase获取所有Cagegory 5.2.2. 实现ICategoryRepository接口3. 实现获取所有Category的方法4. 实现获取一个Cagegory…

人工智能-自动驾驶领域

目录 引言自动驾驶与人工智能的结合为什么自动驾驶领域适合发表文章博雅智信的自动驾驶辅导服务结语 引言 自动驾驶技术的崛起是当代交通行业的一场革命。通过结合先进的人工智能算法、传感器技术与计算机视觉&#xff0c;自动驾驶不仅推动了技术的进步&#xff0c;也使得未来…

Linux系统操作01|文件目录、常用命令

Linux系统操作教程2天快速入门linux项目搭建_哔哩哔哩_bilibili 目录 一、文件和目录 1、Linux和Windows文件系统的区别 2、主要目录 二、Linux常用命令的基本使用 1、cd&#xff1a;切换文件夹 2、ls&#xff1a;查看当前目录下的内容 3、mkdir&#xff1a;创建文件夹…

VMware Workstation Pro 17 下载 以及 安装 Ubuntu 20.04.6 Ubuntu 启用 root 登录

1、个人免费版本 VMware Workstation Pro 17 下载链接怎么找&#xff1f;直接咕咕 VMware 找到如下链接。链接如下&#xff1a;Workstation 和 Fusion 对个人使用完全免费&#xff0c;企业许可转向订阅 - VMware 中文博客 点进去链接之后你会看到如下&#xff0c;注意安装之后仍…

快速将请求头构建成json结构

1.背景 有时候我们要爬虫(组包)请求一个资源数据,需要构建与原始请求一样的请求头,从浏览器复制过来的请求头,有很多,如果一个一个的配置成json有点慢,那么如何快速构建呢? 今天就使用正则表达式的方式实现 正则表达式实现快速将请求头构建成json结构 将冒号后边的换行符去掉…

Cobaltstrike

Cobaltstrike 資源JFrame 图形用户界面mxGraph数据请求stageless beacon http通信协议 数据加密过程分析Scalar 运行时Aggressor Script Event Queue 客户端通讯登录验证 用户管理外部监听添加監聽Beacon 内容构建 PE解析Payload Generator负载生成Dialog动作选择Listener动作G…

Noise2Noise图像去噪

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

基于SpringBoot和PostGIS的全球城市信息管理实践

目录 前言 一、业务需求介绍 1、功能思维导图 二、业务系统后台实现 1、Model层实现 2、业务层的实现 3、控制层的实现 三、前端管理业务的实现 1、全球城市列表的实现 2、详情页面实现 3、实际城市定位 四、总结 前言 在全球化和信息化时代背景下&#xff0c;城市作…

Cocos Creator 开发微信小游戏分包

作为以后端选手,吭哧吭哧的好不容易用cocos开发了一款小游戏, 上传的时候发现包太大了,主包超过4M; 我不是选小游戏分包了吗? 怎么还超? 分包的方案: 功能裁剪资源压缩主包迁移WASM分离 1. 功能裁剪 项目设置中引擎管理器中 功能裁剪里面有很多个引擎,我们剔除掉没用的引…

计算机网络之NAT、代理服务、内网穿透、内网打洞

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 计算机网络之NAT、代理服务、内网穿透、内网打洞 收录于专栏【计算机网络】 本专栏旨在分享学习计算机网络的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论…

【论文阅读】相似误差订正方法在风电短期风速预报中的应用研究

文章目录 概述&#xff1a;摘要1. 引言2. 相似误差订正算法&#xff08;核心&#xff09;3. 订正实验3.1 相似因子选取3.2 相似样本数试验3.3 时间窗时长实验 4. 订正结果分析4.1 评估指标对比4.2 风速曲线对比4.3 分风速段订正效果评估4.4 风速频率统计 5. 结论与讨论 概述&am…

【Rust 学习笔记】Rust 基础数据类型介绍——数组、向量和切片

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 博客内容主要围绕&#xff1a; 5G/6G协议讲解 高级C语言讲解 Rust语言讲解 文章目录 Rust 基础数据类型介绍——数组、向量和切片一、数组、向量和…

爬虫学习案例3

爬取美女图片 优美图库地址 一页图片 安装依赖库文件 pip install selenium requests beautifulsoup4import time import requests import random from bs4 import BeautifulSoup from selenium import webdriver from selenium.webdriver.chrome.service import Service fr…

ubuntu检测是否已安装nvidia驱动以及产品类型

nvidia-sminvidia-smi 是 NVIDIA 提供的一个命令行工具&#xff0c;用于查看和管理 NVIDIA GPU 的状态。当你运行 nvidia-smi 命令时&#xff0c;它会显示当前系统中所有 NVIDIA GPU 的状态信息&#xff0c;包括 GPU 的使用率、温度、内存使用情况等。 有8个GPU nvcc -V查看c…

使用pyinstaller打包pyqt的程序,运行后提示ModuleNotFoundError: No module named ‘Ui_main‘

环境&#xff1a;windowpython3.9pyqt6 使用pyqt UI编辑器生成了main.ui &#xff0c;main.ui编译成了Ui_main.py main.py 使用当前目录下的Ui_main.py。 打包过程没报错&#xff0c;运行报错。 错误如下: 解决方法&#xff1a;pyinstaller -Fw main.py --paths. 使…

MySQL | 尚硅谷 | 第16章_变量、流程控制与游标

MySQL笔记&#xff1a;第16章_变量、流程控制与游标 文章目录 MySQL笔记&#xff1a;第16章_变量、流程控制与游标第16章_变量、流程控制与游标 1. 变量1.1 系统变量1.1.1 系统变量分类1.1.2 查看系统变量 1.2 用户变量1.2.1 用户变量分类1.2.2 会话用户变量 1.2.3 局部变量1.2…

【环境搭建】Jeecg-Boot v3.5.0 Docker搭建

前言 最近需要复现JeecgBoot的SQL注入漏洞&#xff0c;必须要搭建JeecgBoot v3.5.0这个版本才行&#xff0c;DockerHub没人push这个版本的&#xff0c;相关博客也比较少&#xff0c;所以自己来搭建&#xff0c;记录一下过程。 前置环境 Ubuntu 20.04Docker version 27.3.1do…

Certimate自动化SSL证书部署至IIS服务器

前言&#xff1a;笔者上一篇内容已经部署好了Certimate开源系统&#xff0c;于是开始搭建部署至Linux和Windows服务器&#xff0c;Linux服务器十分的顺利&#xff0c;申请证书-部署证书很快的完成了&#xff0c;但是部署至Windows Server的IIS服务时&#xff0c;遇到一些阻碍&a…