shiro-第一篇-基本介绍及使用

news2024/11/15 13:59:11

shiro

概述

shior的话,在第一次听说的时候单纯的任务它就是一个安全框架,可以对访问接口的用户进行验证等工作,类似拦截器或过滤器的东西,但是在学习后,发现远远不止这些,它的灵活性和易用性让我震惊,这么好的东西早就应该发现的呀!!!

特性

​ 既然说了它这么好,让我们来看看它到底好在哪里:

易于使用:使用 Shiro 构建系统安全框架非常简单。就算第一次接触也可以快速掌握。

全面:Shiro 包含系统安全框架需要的功能,满足安全需求的“一站式服务”。

灵活:Shiro 可以在任何应用程序环境中工作。虽然它可以在 Web、EJB 和 IoC 环境 中工作,但不需要依赖它们。Shiro 也没有强制要求任何规范,甚至没有很多依赖项。

强力支持 Web:Shiro 具有出色的 Web 应用程序支持,可以基于应用程序 URL 和 Web 协议(例如 REST)创建灵活的安全策略,同时还提供一组 JSP 库来控制页面输出。

兼容性强:Shiro 的设计模式使其易于与其他框架和应用程序集成。Shiro 与 Spring、Grails、Wicket、Tapestry、Mule、Apache Camel、Vaadin 等框架无缝集成。

看那么多字是不是都很恶心,总结起来就一个字,好用!

spirng security

​ 其实提到安全框架的话,还有一个耳熟能详的框架,就是spring系列的spring security,那这俩有什么区别呢?

  1. spring security是基于spring的,对spring有一定的依赖性,不过当前的话,大部分互联网项目都是基于spring的,所以这个也不能算缺点
  2. spring security功能比shiro更丰富一些,例如安全维护方面
  3. spring security的使用比起shiro来较为复杂

学习方式

​ 在我看来学习任何东西只要掌握其原理和运行流程,其实编码也就好说了,最多也就看看源码之类的东西,知道哪个类是干嘛的,都🆗的,而学习这些东西最好的地方就是官网啦,这里是shiro的官网,里面有更加详尽的介绍及使用,如果有什么问题,里面应该都有解决方案

learning

基本功能及简介

​ 下面就来看看shiro的基本功能吧,以图的方式来展示(摘自apache shiro官网):
在这里插入图片描述

功能介绍:

  1. Authentication:身份认证/登录,验证用户是不是拥有相应的身份
  2. Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限
  3. Session Manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通 JavaSE 环境,也可以是 Web 环境的;
  4. Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储
  5. Web Support:Web 支持,可以非常容易的集成到 Web 环境
  6. Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可以提高效率
  7. Concurrency:Shiro 支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;
  8. Testing:提供测试支持
  9. Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问
  10. Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了

架构概述

​ 在最高概念层面上,Shiro的架构有3个主要概念:Subject、SecurityManager和Realms。下图是这些组件如何交互的高级概述(摘自apache shiro官网):
在这里插入图片描述

组件介绍:

  1. Subject:这里通常指与软件交互的任何东西,通常指用户

  2. SecurityManager:shiro架构的核心,所有和安全相关的操作都会与之交互,它管理所有的subject,类似于springmvc中的DispatcherServlet

  3. Realms:充当的是shiro和应用程序安全数据之间的桥梁,当需要实际与安全相关的数据(如用户帐户)进行交互以执行身份验证(登录)和授权(访问控制)时,Shiro 会从为应用程序配置的一个或多个 Realm 中查找其中的许多内容

    简单来说,可以把Realm看作是一个一个的特定的dao,它封装了数据源的连接细节,并根据需要提供数据给shiro,可以配置多个,但是至少提供一个Realm

详细架构

​ 下图显示了 Shiro 的核心架构概念以及每个概念的简短摘要(摘自apache shiro官网):

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-moiBv4d1-1669008965948)(assets/ShiroArchitecture.png)]

  • Subject( org.apache.shiro.subject.Subject ) 当前与软件交互的实体(用户、第 3 方服务、cron 作业等)的特定于安全的“视图”。
  • SecurityManager ( org.apache.shiro.mgt.SecurityManager ) 主要是用来协调其他组件顺利工作的
  • Authenticator ( org.apache.shiro.authc.Authenticator ) 负责Subject认证,可以自定义实现
    • Authentication Strategy ( org.apache.shiro.authc.pam.AuthenticationStrategy )是身份认证策略,当定义了多个Realm,它就可以去使用指定的策略去进行认证
  • Authorizer ( org.apache.shiro.authz.Authorizer )负责访问控制,是最终决定是否允许用户做某事的机制
  • SessionManager ( org.apache.shiro.session.mgt.SessionManager )负责管理session生命周期,不仅可以用在web环境
    • SessionDAO ( org.apache.shiro.session.mgt.eis.SessionDAO ) 负责代表SessionManager执行增删改查操作,这允许任何数据插入会话管理基础结构
  • CacheManager ( org.apache.shiro.cache.CacheManager )负责创建和管理其他shiro组件使用的缓存实例的生命周期
  • Cryptography ( org.apache.shiro.crypto.* )的中文释义是密码学,很自然的可以想到,安全框架肯定会包含加密模块,在数据方面进行加密
  • Realm( org.apache.shiro.realm.Realm )就没什么好说的了,和上面的意思一样,充当的是shiro和应用程序安全数据之间的桥梁

术语

  • 身份:验证身份是验证用户身份的过程

  • 授权:也称为访问控制,是确定用户是否被允许做某件事的过程

  • 凭证:是验证用户身份的一条信息,只有用户自己知道

  • 权限:至少在 Shiro 的解释中,权限是一种描述应用程序中原始功能的声明,仅此而已。权限是安全策略中最低级别的结构。它们仅定义应用程序可以做什么。他们没有描述“谁”能够执行这些操作。许可只是一种行为声明,仅此而已。

  • 主体(Subject):访问应用的用户,在 Shiro 中使用 Subject 代表该用户。用户只 有授权 后才允许访问相应的资源。

  • 角色(Role):权限的集合,一般情况下会赋予用户角色而不是权限,即这样用户可以拥有一组权限,赋予权限时比较方便。

基本使用

登录认证

流程:

  1. 收集用户身份和凭证,即用户名和密码
  2. 调用subject.login进行登录,如果失败则报异常AuthenticationException
  3. 创建自定义的Realm类,继承org.apache.shiro.realm.AuthenticatingRealm类,实现doGetAuthenticationInfo()方法

身份认证

流程:

  1. 首先调用 Subject.login(token) 进行登录,其会自动委托给 SecurityManager
  2. SecurityManager 负责真正的身份验证逻辑;它会委托给 Authenticator 进行身份验证
  3. Authenticator 才是真正的身份验证者,Shiro API 中核心的身份认证入口点,此处可以自定义插入自己的实现
  4. Authenticator 可能会委托给相应的 AuthenticationStrategy 进行多 Realm 身份验证,默认 ModularRealmAuthenticator 会调用 AuthenticationStrategy 进行多 Realm 身份验证
  5. Authenticator 会把相应的 token 传入 Realm,从 Realm 获取 身份验证信息,如果没有返回/抛出异常表示身份验证失败了。此处 可以配置多个Realm,将按照相应的顺序 及策略进行访问

角色授权

流程:

  1. 首先调用Subject.isPermitted/hasRole接口,其会委托给SecurityManager,而 SecurityManager接着会委托给 Authorizer
  2. Authorizer是真正的授权者,如果调用如isPermitted(“user:view”),其首先会让PermissionResolver把字符串转换成相应的Permission实例
  3. 在进行授权之前,其会调用相应的Realm获取Subject相应的角色/权限用于匹配传入的角色/权限
  4. Authorizer会判断Realm的角色/权限是否和传入的匹配,如果有多个Realm,会委托给ModularRealmAuthorizer进行循环判断,如果匹配如isPermitted/hasRole 会返回 true,否则返回false表示授权失败

实例

  • pom文件
<dependencies>
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-core</artifactId>
        <version>1.9.0</version>
    </dependency>
    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.2</version>
    </dependency>
</dependencies>

​ shiro获取权限相关信息可以通过数据库获取,也可以通过shiro.ini文件获取,此处使用后者实现基本演示

  • shiro.ini
# 提供了对根对象 securityManager 及其依赖的配置
[main]
md5CredentialsMatcher = org.apache.shiro.authc.credential.Md5CredentialsMatcher
md5CredentialsMatcher.hashIterations = 3
myrealm = gyl.top.MyRealm
myrealm.credentialsMatcher = $md5CredentialsMatcher
securityManager.realms = $myrealm
# 提供了对用户/密码及其角色的配置,用户名=密码,角色 1,角色 2
[users]
zhangsan = 7174f64b13022acd3c56e2781e098a5f,role1,role2
lisi = l4
# 提供了角色及权限之间关系的配置,角色=权限 1,权限 2
[roles]
role1 = user:insert,user:select
# 这里还有一种叫urls,不过这里并未配置,它主要用来对url拦截相关的配置,
# 想更多了解shiro.ini配置文件
# 可以参考https://blog.csdn.net/u011781521/article/details/74892074
  • 自定义的Realm:这里其实使用了shiro加密的认证方式,在下面的小节中会提到
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.realm.AuthenticatingRealm;
import org.apache.shiro.util.ByteSource;

/**
 * @author GYL
 * @version V1.0
 */
public class MyRealm extends AuthenticatingRealm {

    /**
     * 自定义登录认证方法,shiro的login方法底层会调用该类的认证方法进行认证
     * 需要配置自定义的realm生效,在ini文件中可以配置,或者在springboot中进行配置
     * 该方法只是获取进行对比的信息,认证逻辑还是安装shiro底层认证逻辑完成
     *
     * @param authenticationToken :获取登录信息
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        // 获取身份信息
        String principal = authenticationToken.getPrincipal().toString();
        // 获取凭证信息
        String password = authenticationToken.getCredentials().toString();
        System.out.println("认证信息:" + principal);
        System.out.println("凭证信息:" + password);
        // 访问数据库,获取数据库中存储的数据信息
        if ("zhangsan".equals(principal)) {
            // 数据库中存储着加盐三次迭代的密码
            String passwordInfo = "7174f64b13022acd3c56e2781e098a5f";
            // 创建封装校验逻辑的对象,把数据封装进去,然后返回
            return new SimpleAuthenticationInfo(
                    authenticationToken.getPrincipal(),
                    passwordInfo,
                    ByteSource.Util.bytes("salt"),
                    principal
            );
        }
        return null;
    }
}
  • 测试类
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;

/**
 * @author GYL
 * @version V1.0
 */
public class ShiroTest {
    public static void main(String[] args) {
        // 初始化获取SecurityManager
        IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        SecurityManager manager = factory.getInstance();
        SecurityUtils.setSecurityManager(manager);
        // 获取Subject对象
        Subject subject = SecurityUtils.getSubject();
        // 创建token对象,web应用用户名密码从页面传递
        AuthenticationToken token = new UsernamePasswordToken("zhangsan", "z3");
        // 调用login方法进行登录认证
        try {
            subject.login(token);
            System.out.println("登录成功");
            if (subject.hasRole("role1")) {
                System.out.println("有相关角色");
            }
            if (subject.isPermitted("user:insert")) {
                System.out.println("有相关权限");
            }
        } catch (UnknownAccountException e) {
            e.printStackTrace();
            System.out.println("用户不存在");
        } catch (IncorrectCredentialsException e) {
            e.printStackTrace();
            System.out.println("密码错误");
        } catch (AuthenticationException ae) {
            //unexpected condition? error?
        }
    }
}

shiro加密

​ 在开发中,常会对一些敏感数据进行加密,比如用户的密码等信息

import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.crypto.hash.SimpleHash;

/**
 * @author GYL
 * @version V1.0
 */
public class ShiroMd5 {
    public static void main(String[] args) {
        // 密码明文:
        String password = "z3";
        // 使用md5加密
        Md5Hash md5Hash = new Md5Hash(password);
        System.out.println(md5Hash);
        // 带盐的md5加密,盐就是在密码明文后拼接新字符串,然后再进行加密
        Md5Hash md5Hash1 = new Md5Hash(password, "salt");
        System.out.println(md5Hash1);
        // 为了保证安全,避免被破解还可以多次迭代加密,保证数据安全
        Md5Hash md5Hash2 = new Md5Hash(password, "salt", 3);
        System.out.println(md5Hash2);
        // 使用父类实现加密
        SimpleHash simpleHash = new SimpleHash("MD5", password, "salt", 3);
        System.out.println(simpleHash);

    }
}
  • 有关shiro的基本介绍和使用就到这里,本文章参考了尚硅谷shiro讲解及shiro官方文档

每一点滴的进展,都是缓慢而艰苦的

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

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

相关文章

408 | 【计网】第二章 物理层 回顾

自用冲刺笔记整理。 部分图片来自王道。 加油ヾ(◍∇◍)ノ゙ (一)通信基础 1.信道、信号、带宽、码元、波特、速率/数据率、信源与信宿等基本概念 单向通信、半双工通信(双方都可接发,不能同时)、全双工通信码元:用一个固定时长(码元宽度)的信号波形表示一位k进制数字。 …

高项 风险管理论文

六个过程&#xff1a; 1&#xff0c;规划风险管理&#xff1a;决定如何进行规划和实施项目风险管理活动。 2&#xff0c;识别风险&#xff1a;判断哪些风险会影响项目&#xff0c;并以书面形式记录其特点。 3&#xff0c;实施定性风险分析&#xff1a;对风险概率和影响进行评…

通信原理学习笔记5-2:数字调制——连续相位和恒包络问题(非线性功放、连续相位CP FSK信号、最小频移键控MSK、GMSK)

为了最大程度利用非线性功放&#xff0c;需要降低信号PAPR&#xff0c;这要求信号具有恒包络特性信道带宽有限&#xff0c;需要降低信号带外泄露&#xff08;进而传输失真小&#xff09;&#xff0c;要求信号具有连续相位特性&#xff08;从而高频成分少&#xff09; 波形连续…

[附源码]java毕业设计文章管理系统查重PPT

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

让你不在为设计商品详情页而烦恼的工具

不想使用之前的详情页设计模板想更换怎么办&#xff1f;不满意自己用软件设计的详情页模板怎么办&#xff1f;下面跟着小编&#xff0c;教你使用这个在线设计工具乔拓云&#xff0c;在工具内不仅有大量的详情页设计模板&#xff0c;还有海量的详情页免扣设计素材能直接使用&…

[附源码]java毕业设计小区物业管理系统论文

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

springmvc-ssm整合

前言:在座的各位大佬好&#xff0c;最近学习了ssm&#xff0c;然后这是一篇整合ssm的笔记&#xff0c;参考的网上某马视频课的笔记嘿嘿~SSM整合需要掌握↓↓↓↓↓↓↓↓一、SSM整合【重点】1 SSM整合配置问题导入1.1 SSM整合流程1.2 SSM整合配置1.2.1 创建工程&#xff0c;添加…

2022年度中国PCB百强榜单公布

近日&#xff0c;2022慕尼黑华南电子展在深圳圆满举办。电巢直播作为电子工程领域流量前沿、专业度高的在线直播平台&#xff0c;参与了本次展会并搭建了“云观展”平台&#xff0c;对展会进行了全程实时直播。 在这场全国性的“电子企业盛会”中&#xff0c;有1100余家来自不…

你真的了解Spring的依赖查找吗?

1.写在前面 前面的博客我们介绍了Spring的总览&#xff0c;今天我们来了解下Spring的依赖查找的相关的内容&#xff0c;我们会从它的前世今生来带你了解下&#xff0c;以及各种类型的查找的方式&#xff0c;同时介绍对应的相对比较安全的查找的方式。以及会介绍一些比较常见的…

分布式系统设计模式和一致性协议,你用过哪些?

1、布隆过滤器 Bloom过滤器是一种节省空间的概率数据结构&#xff0c;用于测试元素是否为某集合的成员。它用于我们只需要检查元素是否属于对象的场景。 在BigTable&#xff08;和Cassandra&#xff09;中&#xff0c;任何读取操作都必须从组成Tablet的SSTable中读取。如果这些…

用于光波导耦合的倾斜光栅分析

1. 摘要 因其在确定衍射级上的高衍射效率&#xff0c;倾斜光栅广泛用于将光耦合到光波导中。如今&#xff0c;倾斜光栅广泛用于增强现实和混合现实应用中。本示例中将示范如何使用VirtualLab Fusion分析文献中具有特定参数的某些倾斜光栅的几何形状&#xff08;例如倾斜角、填充…

Word控件Spire.Doc 【图像形状】教程(1) ;如何在 Word 中插入图像(C#/VB.NET)

Spire.Doc for .NET是一款专门对 Word 文档进行操作的 .NET 类库。在于帮助开发人员无需安装 Microsoft Word情况下&#xff0c;轻松快捷高效地创建、编辑、转换和打印 Microsoft Word 文档。拥有近10年专业开发经验Spire系列办公文档开发工具&#xff0c;专注于创建、编辑、转…

使用OpenCV计算两幅图像的协方差

要计算协方差首先要知道协方差的数学原理。 定义 Cov(X,Y) E{ [X-E(X)][Y-E(Y)] }为随机量X与Y的协方差。 其中E(X)为随机变量X的期望(均值)&#xff0c;E(Y)为随机变量Y的期望(均值)。 我们通常用下面的这个公式计算协方差。 Cov(X,Y)E(XY)-E(X)E(Y) 另外&#xff0c;大家…

【苹果家庭群发推送】软件安装最新的Appletweetios.macosimessage是用于发送Apple文本消息

推荐内容IMESSGAE相关 作者推荐内容iMessage苹果推软件 *** 点击即可查看作者要求内容信息作者推荐内容1.家庭推内容 *** 点击即可查看作者要求内容信息作者推荐内容2.相册推 *** 点击即可查看作者要求内容信息作者推荐内容3.日历推 *** 点击即可查看作者要求内容信息作者推荐…

单商户商城系统功能拆解33—营销中心—包邮活动

单商户商城系统&#xff0c;也称为B2C自营电商模式单店商城系统。可以快速帮助个人、机构和企业搭建自己的私域交易线上商城。 单商户商城系统完美契合私域流量变现闭环交易使用。通常拥有丰富的营销玩法&#xff0c;例如拼团&#xff0c;秒杀&#xff0c;砍价&#xff0c;包邮…

热门Java开发工具IDEA入门指南——从Eclipse迁移到IntelliJ IDEA(三)

IntelliJ IDEA&#xff0c;是java编程语言开发的集成环境。IntelliJ在业界被公认为最好的java开发工具&#xff0c;尤其在智能代码助手、代码自动提示、重构、JavaEE支持、各类版本工具(git、svn等)、JUnit、CVS整合、代码分析、 创新的GUI设计等方面的功能是非常强大的。 本文…

React 基础

React 基础 1.React概述 目标&#xff1a;了解 React 是什么 官方文档&#xff08;英文&#xff09;,官方文档&#xff08;中文&#xff09; 官方释义&#xff1a; A JavaScript library for building user interfaces &#xff08;一个用于构建用户界面的 JavaScript 库&a…

FT2000+ arm64服务器 kylin server 虚拟机 编译fuse_dfs 解决挂载目录中的故障

服务器搭建 FT2000 arm64服务器 openEuler 部署hadoop单机伪集群并测试基准性能_hkNaruto的博客-CSDN博客 编译fuse相关程序 下载源码 wget https://dlcdn.apache.org/hadoop/common/hadoop-3.3.1/hadoop-3.3.1-src.tar.gz tar -xvf hadoop-3.3.1-src.tar.gz 安装工具、编…

干货!一文搞定无头浏览器的概念以及在selenium中的应用

无头浏览器 无头浏览器&#xff0c;即 Headless Browser&#xff0c;是一种没有界面的浏览器。它拥有完整的浏览器内核&#xff0c;包括 JavaScript 解析引擎、渲染引擎等。与普通浏览器最大的不同是&#xff0c;无头浏览器执行过程中看不到运行的界面&#xff0c;但是我们依然…

目标检测算法——工业缺陷数据集汇总2(附下载链接)

>>>深度学习Tricks&#xff0c;第一时间送达<<< &#x1f680;近期&#xff0c;小海带在空闲之余&#xff0c;收集整理了一批工业缺陷开源数据集供大家参考。 整理不易&#xff0c;小伙伴们记得一键三连喔&#xff01;&#xff01;&#xff01;&#x1f91e…