Shiro框架

  1. 定义
    • Shiro 是一个强大的、易用的 Java 安全框架,它可以帮助开发者处理身份验证(Authentication)、授权(Authorization)、加密(Cryptography)和会话管理(Session Management)等应用程序安全相关的功能。Shiro 的设计理念是简单、灵活且功能强大,它可以在 Java SE 和 Java EE 环境中使用。
  2. 主要功能
    • 身份验证
      • 这是确定用户身份的过程。Shiro 提供了多种身份验证方式,例如通过用户名 / 密码组合来验证用户身份。它支持多种数据源,如关系数据库、LDAP(轻型目录访问协议)等。例如,在一个 Web 应用中,用户在登录页面输入用户名和密码,Shiro 可以获取这些信息并与存储在数据库中的用户凭证进行比对,以确定用户是否是合法用户。
    • 授权
      • 授权是确定已认证用户是否有权访问特定资源的过程。Shiro 支持基于角色(Role - Based Access Control,RBAC)和基于权限(Permission - Based Access Control,PBAC)的授权方式。以一个企业资源管理系统为例,管理员角色的用户可能有权限访问和修改所有员工的信息,而普通员工角色的用户可能只能访问自己的信息。Shiro 可以根据用户的角色或权限来控制用户对系统不同功能模块的访问。
    • 加密
      • Shiro 提供了简单易用的加密功能,用于保护数据的安全性。它支持多种加密算法,如 MD5、SHA - 1 等。在存储用户密码时,不应该以明文形式存储,Shiro 可以对密码进行加密处理,然后将加密后的密码存储在数据库中。当用户登录验证时,对输入的密码进行同样的加密操作,再与存储的加密密码进行比对,这样可以防止密码泄露导致的安全风险。
    • 会话管理
      • Shiro 提供了自己的会话管理机制,它可以独立于 Web 容器的会话管理。这对于一些分布式系统或者需要精细控制会话的场景非常有用。例如,在一个分布式的微服务架构中,不同的服务可能需要共享用户的会话信息,Shiro 可以帮助管理这些会话,确保用户在不同服务之间的交互过程中会话的一致性和安全性。
  3. 架构组成
    • Subject:这是 Shiro 的核心概念之一,它代表了当前与软件系统进行交互的用户、设备或其他系统主体。可以把 Subject 看作是一个门面,通过它可以方便地进行身份验证、授权等操作。例如,在一个 Web 应用中,当一个用户访问一个受保护的资源时,这个用户就对应一个 Subject。
    • SecurityManager:它是 Shiro 的核心管理组件,负责协调和管理 Shiro 的各个模块,如身份验证、授权、会话管理等。SecurityManager 就像是一个指挥官,指挥着整个安全系统的运作。所有 Subject 的操作都会委托给 SecurityManager 来执行。
    • Realms:Realms 是 Shiro 与应用程序安全数据(如用户、角色和权限)的数据源进行交互的桥梁。它可以从不同的数据源(如数据库、LDAP 服务器等)获取安全相关的数据,以支持身份验证和授权操作。例如,如果用户信息存储在关系数据库中,就可以创建一个数据库 Realm 来从数据库中读取用户凭证、角色和权限等信息。

Shiro的运行流程:Shiro 运行的典型流程

  • 身份验证流程
    • Subject 发起认证请求:当 Subject(比如用户在登录页面输入用户名和密码后点击登录)需要进行身份验证时,它会调用SecurityManager.login()方法,并将包含用户凭证(如用户名和密码)的AuthenticationToken传递进去。
    • SecurityManager 处理请求:SecurityManager 接收到认证请求后,会将任务委托给内部的Authenticator组件。
    • Authenticator 与 Realm 交互:Authenticator 会调用配置的一个或多个 Realms 来获取用户身份信息进行验证。Realm 会根据传入的AuthenticationToken中的信息(如用户名)从数据源(如数据库)中查找对应的用户记录,并比较密码等凭证是否匹配。
    • 返回认证结果:如果 Realm 验证通过,Authenticator 会返回一个成功的认证信息给 SecurityManager,SecurityManager 再将认证成功的信息返回给 Subject,此时 Subject 就被标记为已认证状态。如果验证失败,会抛出相应的异常,如UnknownAccountException(账号不存在)、IncorrectCredentialsException(密码错误)等。

shiro如何对密码继续加密

  1. 使用 Shiro 自带的加密工具
    • Shiro 提供了SimpleHash类来进行密码加密。它支持多种哈希算法,如 MD5、SHA - 1、SHA - 256 等。
    • 示例代码
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.util.ByteSource;
public class ShiroPasswordEncryption {public static void main(String[] args) {// 原始密码String password = "123456";// 哈希算法名称,这里使用MD5String algorithmName = "MD5";// 盐值(可以是随机生成的字符串),增强安全性String salt = "random_salt";// 哈希次数int hashIterations = 1024;// 使用SimpleHash进行加密SimpleHash hash = new SimpleHash(algorithmName, password, ByteSource.Util.bytes(salt), hashIterations);System.out.println("加密后的密码: " + hash.toHex());}
}
  • 在这个示例中,SimpleHash构造函数接收哈希算法名称、原始密码、盐值(字节数组形式)和哈希次数。ByteSource.Util.bytes(salt)是将盐值转换为字节数组的操作。最后,hash.toHex()将加密后的哈希值转换为十六进制字符串方便存储和比较。
  1. 加盐(Salt)机制在 Shiro 中的应用
    • 为什么要加盐:加盐可以增加密码破解的难度。如果没有盐值,攻击者可以使用预先计算好的彩虹表(包含常见密码和对应的哈希值)来快速找到密码。而加盐后,即使密码相同,由于盐值不同,哈希值也不同,使得彩虹表攻击失效。
    • 在 Shiro 中配置盐值:可以在自定义的Realm(Shiro 用于获取安全数据的组件)实现中设置盐值。例如,在AuthenticatingRealm的子类中:
public class MyRealm extends AuthenticatingRealm {@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {// 假设从数据库或其他数据源获取用户信息String username = (String) token.getPrincipal();User user = userDao.findUserByUsername(username);if (user == null) {throw new UnknownAccountException("用户不存在");}// 获取盐值,假设用户对象中有盐值属性String salt = user.getSalt();// 创建SimpleAuthenticationInfo对象,传入盐值SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), ByteSource.Util.bytes(salt), getName());return info;}
}
  • 在这个MyRealm类的doGetAuthenticationInfo方法中,从数据源获取用户的盐值,然后在创建SimpleAuthenticationInfo对象时,将盐值(字节数组形式)传入。这样在验证密码时,Shiro 会使用相同的盐值来重新计算哈希值并与存储的密码哈希值进行比较。
  1. 与其他加密方式集成(如 BCrypt)
    • 使用 BCrypt 加密器:BCrypt 是一种更安全的密码加密方式。虽然 Shiro 本身有加密工具,但也可以将 BCrypt 集成进来。
    • 示例代码(使用 Spring Boot 和 Shiro 集成 BCrypt)
      • 首先添加spring - security - crypto依赖(因为 BCrypt 加密工具在这个库中):
<dependency><groupId>org.springframework.security</groupId><artifactId>spring - security - crypto</artifactId>
</dependency>
  • 然后在自定义的Realm或者密码处理类中使用 BCrypt:
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
public class PasswordEncryptionWithBCrypt {public static void main(String[] args) {BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();String password = "123456";String encryptedPassword = encoder.encode(password);System.out.println("加密后的密码: " + encryptedPassword);boolean matches = encoder.matches("123456", encryptedPassword);System.out.println("密码匹配结果: " + matches);}
}
  • 这种方式利用了 Spring Security 提供的 BCrypt 加密工具,通过BCryptPasswordEncoder类来进行密码加密和验证。在 Shiro 的Realm中,可以在doGetAuthenticationInfo方法等地方使用类似的加密方式来处理密码,以增强密码的安全性。

Shiro怎么使用?

  1. 引入 Shiro 依赖
    • 如果你使用的是 Maven 项目,需要在pom.xml文件中添加 Shiro 依赖。例如:
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro - core</artifactId><version>1.10.0</version>
</dependency>
  • 对于 Gradle 项目,则在build.gradle文件中添加:
implementation 'org.apache.shiro:shiro - core:1.10.0'

  1. 创建自定义 Realm(数据源)
    • Realm 是 Shiro 获取安全数据(如用户、角色和权限)的地方,相当于数据源。
    • 自定义 Realm 需要继承AuthorizingRealm类,并重写doGetAuthenticationInfodoGetAuthorizationInfo方法。
    • 示例代码如下:
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
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 MyRealm extends AuthorizingRealm {// 模拟用户数据存储(实际应用中可能是数据库等)private static final Set<String> userCredentials = new HashSet<>();private static final Set<String> userRoles = new HashSet<>();private static final Set<String> userPermissions = new HashSet<>();static {userCredentials.add("user1:password1");userRoles.add("user1:role1");userPermissions.add("user1:permission1");}@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {String username = (String) token.getPrincipal();String password = null;for (String userCredential : userCredentials) {String[] parts = userCredential.split(":");if (parts[0].equals(username)) {password = parts[1];break;}}if (password == null) {throw new AuthenticationException("用户不存在");}return new SimpleAuthenticationInfo(username, password, getName());}@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {String username = (String) principals.getPrimaryPrincipal();SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();for (String userRole : userRoles) {String[] parts = userRole.split(":");if (parts[0].equals(username)) {authorizationInfo.addRole(parts[1]);}}for (String userPermission : userPermissions) {String[] parts = userPermission.split(":");if (parts[0].equals(username)) {authorizationInfo.addStringPermission(parts[1]);}}return authorizationInfo;}
}
  • doGetAuthenticationInfo方法中,根据传入的用户名(从AuthenticationToken获取)查找对应的密码,如果找不到用户则抛出异常,找到则返回包含用户名、密码和 Realm 名称的SimpleAuthenticationInfo
  • doGetAuthorizationInfo方法中,根据用户名查找对应的角色和权限,将它们添加到SimpleAuthorizationInfo中并返回
  1. 配置 SecurityManager
    • SecurityManager 是 Shiro 的核心组件,用于管理安全操作。
    • 示例代码如下:
import org.apache.shiro.SecurityManager;
import org.apache.shiro.mgt.DefaultSecurityManager;
public class ShiroConfig {public static SecurityManager getSecurityManager() {DefaultSecurityManager securityManager = new DefaultSecurityManager();securityManager.setRealm(new MyRealm());return securityManager;}
}
  • 这里创建了一个DefaultSecurityManager,并将自定义的MyRealm设置给它。
  1. 使用 Shiro 进行身份验证和授权
    • 身份验证示例
import org.apache.shiro.SecurityManager;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import static com.example.shiro.ShiroConfig.getSecurityManager;
public class ShiroAuthenticationExample {public static void main(String[] args) {SecurityManager securityManager = getSecurityManager();// 将SecurityManager设置到当前线程环境org.apache.shiro.util.ThreadContext.bind(securityManager);Subject subject = org.apache.shiro.subject.Subject.Builder.create().build();UsernamePasswordToken token = new UsernamePasswordToken("user1", "password1");try {subject.login(token);System.out.println("身份验证成功");} catch (Exception e) {System.out.println("身份验证失败: " + e.getMessage());}}
}
  • 在这个示例中,首先获取SecurityManager并绑定到当前线程环境,然后创建Subject,通过UsernamePasswordToken传入用户名和密码进行登录操作。如果登录成功,说明身份验证通过。
  • 授权示例
import org.apache.shiro.SecurityManager;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import static com.example.shiro.ShiroConfig.getSecurityManager;
public class ShiroAuthorizationExample {public static void main(String[] args) {SecurityManager securityManager = getSecurityManager();// 将SecurityManager设置到当前线程环境org.apache.shiro.util.ThreadContext.bind(securityManager);Subject subject = org.apache.shiro.subject.Subject.Builder.create().build();UsernamePasswordToken token = new UsernamePasswordToken("user1", "password1");try {subject.login(token);if (subject.hasRole("role1")) {System.out.println("用户具有role1角色");}if (subject.isPermitted("permission1")) {System.out.println("用户具有permission1权限");}} catch (Exception e) {System.out.println("身份验证或授权失败: " + e.getMessage());}}
}
  • 这里在身份验证成功后,通过subject.hasRolesubject.isPermitted方法来检查用户是否具有特定的角色和权限。

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

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

相关文章

以太网交换安全:MAC地址漂移

一、什么是MAC地址漂移&#xff1f; MAC地址漂移是指设备上一个VLAN内有两个端口学习到同一个MAC地址&#xff0c;后学习到的MAC地址表项覆盖原MAC地址表项的现象。 MAC地址漂移的定义与现象 基本定义&#xff1a;MAC地址漂移发生在一个VLAN内的两个不同端口学习到相同的MAC地…

.NET6中WPF项目添加System.Windows.Forms引用

.NET6中WPF项目添加System.Windows.Forms引用 .NET6的WPF自定义控件默认是不支持System.Windows.Forms引用的&#xff0c;需要添加这个引用方法如下&#xff1a; 1. 在项目浏览器中找到项目右击&#xff0c;选择编辑项目文件&#xff08;Edit Project File&#xff09;。 …

Docker安装XXL-JOB分布式调度任务

一、持久化 1、下载 xxl-job 源码,找到持久化脚本 2、创建 xxl-job 数据库,将上述文件中的脚本在本库执行即可 create database xxl_job charset utf8mb4 collate utf8mb4_general_ci; 二、安装 1、下载 xxl-job 镜像 docker pull xuxueli/xxl-job-admin:2.4.1 2、创建挂…

Kafka 源码 KRaft 模式本地运行

KRaft&#xff08;Kafka Raft Metadata mode&#xff09;&#xff0c;从版本 2.8.0 开始作为测试特性引入&#xff0c;并在后续版本中持续得到改进和增强。 KRaft 模式是指 Kafka 使用 Raft 协议来管理集群元数据的一种运行模式&#xff0c;这标志着 Kafka 向去除对 ZooKeeper …

杨辉三角,洗牌算法

杨辉三角 给定一个非负整数numRows&#xff0c;生成杨辉三角的前numRows行。 在杨辉三角中&#xff0c;每个数是它的左上方和右上方的数的和。 public List<List<Integer>> generate(int numRows){List<List<Integer>> ret new ArrayList<>();…

计算机网络——HTTP篇

基础篇 IOS七层网络模型 TCP/IP四层模型&#xff1f; 应⽤层&#xff1a;位于传输层之上&#xff0c;主要提供两个终端设备上的应⽤程序之间的通信&#xff0c;它定义了信息交换的格式&#xff0c;消息会交给下⼀层传输层来传输。 传输层的主要任务就是负责向两台设备进程之间…

基于SpringBoot的Java教学支持系统开发指南

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理教学辅助平台的相关信息成为必然。开发合适…

MySQL:表的增删改查(进阶)

表的增删改查&#xff08;进阶&#xff09;十分重要&#xff0c;也较有难度&#xff0c;需多花时间掌握。 一、NULL约束&#xff1a; 在加null约束之前&#xff0c;id可以插入null&#xff0c;在加上null约束之后&#xff0c;id不再可以插入null。 二、unique约束&#xff1a;…

Latex中给公式加边框

1、这里使用的不是 amsmath 的 \boxed 命令, 而是 empheq 的 empheq 环境以及 xcolor 的 \fcolorbox 命令, 下面是代码, 可以分别阅读这两个手册来获取更多的信息 \documentclass{article} \usepackage{xcolor} \usepackage{empheq} \usepackage{amsmath} \begin{document}\be…

VMware Workstation安装Centos系统

准备虚拟机和镜像文件 1. 安装虚拟机 安装虚拟机VMware Workstation&#xff0c;可以去官网下载自己需要的版本&#xff0c;如果已经安装可继续看后续步骤。安装链接&#xff1a;https://vmware.710down.com/?bd_vid14012951182566760856 2.下载镜像文件 阿里云镜像地址&a…

简单又便宜的实现电脑远程开机唤醒方法

现有的远程开机方案 1&#xff09;使用向日葵开机棒 缺点是比较贵一点&#xff0c;开机棒要一百多&#xff0c;而且查了评论发现挺多差评说不稳定&#xff0c;会有断联和无法唤醒的情况&#xff0c;而且设置也麻烦&#xff0c;还需要网卡支持WOL 2&#xff09;使用远程开机卡 …

WordCloudStudio:AI生成模版为您的文字云创意赋能 !

在信息泛滥的时代&#xff0c;如何有效地将文字内容变成生动的视觉元素&#xff1f;WordCloudStudio为您提供了答案。无论您是市场营销专家、教育工作者、数据分析师&#xff0c;还是创意设计师&#xff0c;WordCloudStudio都能帮助您轻松创建引人注目的文字云。更重要的是&…

低压线路保护器在生产型企业配电系统中的应用

摘要 随着现代电力系统的发展&#xff0c;配电系统的可靠性和安全性要求日益提高。低压线路保护器在其中扮演着关键角色。本文将探讨低压线路保护器的工作原理及其在现代配电系统中的作用&#xff0c;重点介绍ALP系列低压线路保护器的功能与应用。 引言 低压线路保护器用于保…

解决:ros进行gazebo仿真,rviz没有显示传感器数据

目录 前言解决总结 前言 看了很多urdf、xacro文件的编写&#xff0c;每次看了都觉得自己会了&#xff0c;然后自己写一点&#xff0c;就是废物了。 在我这里的案例是&#xff0c;我在一个大方块上面&#xff0c;添加了两个VLP-16的雷达&#xff0c;然后我想获取雷达扫描的数据…

Android——多线程、线程通信、handler机制

Android——多线程、线程通信、handler机制 模拟网络请求&#xff0c;会阻塞主线程 private String getStringForNet() {StringBuilder stringBuilder new StringBuilder();for (int i 0; i < 100; i) {stringBuilder.append("字符串" i);}try {Thread.sleep(…

Linux(ubuntu) 部署xinference

注:在此前提我已经准备好了环境 - 文章中大部分命令我都会有说明 进阶命令就需要友友们在研究了 miniconda 安装 gpu 显卡驱动安装 xinference使用命令什么的我就不放了官方文档中很简单易懂 xinference 官方文档地址 注&#xff1a;此文章不叙述docker版安装(docker安装很简单…

界面控件DevExpress WPF中文教程:Data Grid——卡片视图设置

DevExpress WPF拥有120个控件和库&#xff0c;将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序&#xff0c;这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件…

Flutter PC端UI组件库

一、参考Element-ui的设计和交互&#xff0c;构建基于dart的Flutter UI组件库 https://javonhuang.github.io/sky-ui-page/index.html

Java Development Kit (JDK) 详解

什么是 JDK&#xff1f; JDK 是 Java Development Kit 的缩写&#xff0c;是一组用于开发 Java 应用程序的软件开发工具和库的集合。JDK 包含了 Java 运行时环境&#xff08;JRE&#xff09;和 Java 虚拟机&#xff08;JVM&#xff09;&#xff0c;以及一系列开发工具和库。 …

基于卷积神经网络的农作物病虫害识别系统(pytorch框架,python源码)

更多图像分类、图像识别、目标检测等项目可从主页查看 功能演示&#xff1a; 基于卷积神经网络的农作物病虫害检测&#xff08;pytorch框架&#xff09;_哔哩哔哩_bilibili &#xff08;一&#xff09;简介 基于卷积神经网络的农作物病虫害识别系统是在pytorch框架下实现的…