shiro-第一篇-基本介绍及使用
创始人
2024-02-05 14:52:46

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文件
org.apache.shiroshiro-core1.9.0commons-loggingcommons-logging1.2

​ 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 :获取登录信息*/@Overrideprotected 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) {// 初始化获取SecurityManagerIniSecurityManagerFactory 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官方文档

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

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...