Shiro学习总结

第一章 入门概述

1.概念

shiro是一个Java安全框架,可以完成:认证、授权、加密、会话管理、与web集成、缓存…

2.优势

● 易于使用,构建简单
● 功能全面
● 灵活,可以在任何应用程序环境中工作,并且不需要依赖它们
● 高效支持web,可以基于应用程序URL和Web协议创建灵活的安全策略
● 兼容性强,易于和其他框架和应用程序集成
● 社区支持

3.与springsecurity的区别

● shiro需要和spring整合开发,而springsecurity基于spring开发,配合起来更便利
● springsecurity比shiro功能丰富,如安全维护
● shiro配置和使用简单,springsecurity较难
● shiro依赖性低,不需要任何框架和容器,可以独立运行,而springsecurity需要依赖spring容器
● shiro可以工作于任何应用环境,独立于容器

4.基本功能

在这里插入图片描述

  1. Authentication:身份认证/登录,验证用户是否拥有对应的身份
  2. authorization:权限验证,验证用户是否拥有某个权限,判断用户可以进行什么操作
  3. session management:会话管理,即用户登录后的一次会话,在没有登出之前,所有的信息都保存在会话中
  4. cryptography:加密,保证数据的安全,比如密码加密存储数据库
  5. web support:web支持,集成web环境
  6. caching:缓存,比如用户登录后,用户信息、角色和权限保存下来
  7. concurrency:多线程并发验证,比如在一个线程红开启另一个线程,可以把权限自动传播过去
  8. Testing:测试功能
  9. run as:伪装用户
  10. remember me:记住我

5.原理

shiro外部架构
在这里插入图片描述

subject:对外API核心,与应用代码直接交互的对象,与subject的所有交互都会委托为securitymanager
securitymanager:安全管理器,所有与安全相关的操作都会与securitymanager交互,管理所有的subject,是shiro的核心,相当于spingmvc的dispatcherservlet的角色
realm:从realm中获取安全数据信息(用户、角色、权限)

shiro内部架构

在这里插入图片描述

  • Subject:任何可以与应用交互的“用户”
  • SecurityManager :相当于 SpringMVC 中的 DispatcherServlet;是 Shiro 的心脏; 所有具体的交互都通过 SecurityManager 进行控制;它管理着所有 Subject、且负责进 行认证、授权、会话及缓存的管理
  • Authenticator:负责 Subject 认证,是一个扩展点,可以自定义实现;可以使用认证策略(Authentication Strategy),即什么情况下算用户认证通过了
  • Authorizer:授权器、即访问控制器,用来决定主体是否有权限进行相应的操作;即控制着用户能访问应用中的哪些功能
  • Realm:可以有 1 个或多个 Realm,可以认为是安全实体数据源,即用于获取安全实体的;可以是 JDBC 实现,也可以是内存实现等等;由用户提供;所以一般在应用中都需要实现自己的 Realm
  • SessionManager:管理 Session 生命周期的组件
  • CacheManager:缓存控制器,来管理如用户、角色、权限等的缓存的;因为这些数据 基本上很少改变,放到缓存中后可以提高访问的性能
  • Cryptography:密码模块,Shiro 提高了一些常见的加密组件用于如密码加密/解密。

第二章 基本使用

1.环境搭建
● 引入依赖

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

● ini文件:src/main/resources/shiro.ini

[users]
zhangsan=z3
lisi=l4

2.登录认证

概念:
① 身份验证:一般需要提供如身份ID等一些标识信息来表明登录者的身份,如提供email,用户名/密码来证明
② 在shiro中,用户需要提供principals(身份)和credentials(证明)给shiro,从而应用能验证用户身份
③ principals:身份,即主体的标识属性,可以是任何属性,如用户名、邮箱等,唯一即可。一个主体可以有多个principals,但只有一个Primary principals,一般是用户名/邮箱/手机号
④ credentials:证明/凭证,即只有主体知道的安全值,如密码/数字证书等
最常见的principals和credentials组合就是用户名/密码
流程:
① 收集用户身份/凭证,即如用户名/密码
② 调用 Subject.login 进行登录,如果失败将得到相应 的 AuthenticationException异常,根据异常提示用户 错误信息;否则登录成功
③ 创建自定义的 Realm 类,继承 org.apache.shiro.realm.AuthenticatingRealm类,实现 doGetAuthenticationInfo() 方法
实例:

public class ShiroRun {public static void main(String[] args) {//1.初始化获取securitymanagerIniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini");SecurityManager securityManager = factory.getInstance();SecurityUtils.setSecurityManager(securityManager);//2.获取subject对象Subject subject = SecurityUtils.getSubject();//3.创建token对象,web应用用户名密码从页面传递AuthenticationToken token = new UsernamePasswordToken("zhangsan", "z3");//4.完成登录try {subject.login(token);System.out.println("login successful");} catch (UnknownAccountException e) {e.printStackTrace();System.out.println("用户不存在");}catch (IncorrectCredentialsException e) {e.printStackTrace();System.out.println("密码错误");}catch (AuthenticationException e) {e.printStackTrace();System.out.println("登录失败");}}
}

3.授权

① 授权,也叫访问控制,即在应用中控制谁访问哪些资源(如访问页面/编辑数据/页面 操作等)。在授权中需了解的几个关键对象:主体(Subject)、资源(Resource)、权限 (Permission)、角色(Role)
② 主体(Subject):访问应用的用户,在 Shiro 中使用 Subject 代表该用户。用户只有授权 后才允许访问相应的资源
③ 资源(Resource):在应用中用户可以访问的 URL,比如访问 JSP 页面、查看/编辑 某些 数据、访问某个业务方法、打印文本等等都是资源。用户只要授权后才能访问
④ 权限(Permission):安全策略中的原子授权单位,通过权限我们可以表示在应用中用户 有没有操作某个资源的权力。即权限表示在应用中用户能不能访问某个资源,如:访问用 户列表页面查看/新增/修改/删除用户数据(即很多时候都是CRUD(增查改删)式权限控 制)等。权限代表了用户有没有操作某个资源的权利,即反映在某个资源上的操作允不允许
⑤ Shiro 支持粗粒度权限(如用户模块的所有权限)和细粒度权限(操作某个用户的权限, 即实例级别的)
⑥ 角色(Role):权限的集合,一般情况下会赋予用户角色而不是权限,即这样用户可以拥有 一组权限,赋予权限时比较方便。典型的如:项目经理、技术总监、CTO、开发工程师等都是角色,不同的角色拥有一组不同的权限
授权方式:

  • 编程式:subject.hasRole("admin")
  • 注解式:@RequiresRoles("admin")
  • jsp/gsp标签:<shiro:hasRole name="admin"></shiro:hasRole>

授权流程:

  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表示授权失败
    在这里插入图片描述

实例:

1.给shiro.ini增加角色配置

[users]
fate=admin,role1,role2
fuck=123456

2.增加权限配置

[roles]
role1=user:insert,user:select

3.测试代码

public static void main(String[] args) {//1.初始化获取securitymanagerIniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini");SecurityManager securityManager = factory.getInstance();SecurityUtils.setSecurityManager(securityManager);//2.获取subject对象Subject subject = SecurityUtils.getSubject();//3.创建token对象,web应用用户名密码从页面传递AuthenticationToken token = new UsernamePasswordToken("zhangsan", "z3");//4.完成登录try {subject.login(token);System.out.println("login successful");//5.判断角色boolean hasRole = subject.hasRole("role1");System.out.println("是否拥有role1角色:" + hasRole);//6.判断权限boolean permitted = subject.isPermitted("user:insert");System.out.println("是否拥有此权限:" + permitted);//也可以用checkPermission方法,但没有返回值,没权限抛AuthenticationExceptionsubject.checkPermission("user:update");} catch (UnknownAccountException e) {e.printStackTrace();System.out.println("用户不存在");} catch (IncorrectCredentialsException e) {e.printStackTrace();System.out.println("密码错误");} catch (AuthenticationException e) {e.printStackTrace();System.out.println("登录失败");}
}

4.加密
Shiro内嵌很多常用的加密算法,比如MD5加密

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

5.自定义登录认证
Shiro 默认的登录认证是不带加密的,如果想要实现加密认证需要自定义登录认证, 自定义Realm

public class MyRealm extends AuthenticatingRealm {//自定义登录认证方法,shiro的login方法的底层会调用该类的认证方法进行认证//需要配置自定义的realm生效,应该在ini文件中配置,如果有springboot框架,也可以在Springboot中进行配置//该方法只是获取进行对比的信息,认证逻辑还是按照shiro的底层认证逻辑来完成protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {//1.获取身份信息String principal = authenticationToken.getPrincipal().toString();//2.获取凭证信息String password = new String((char[]) authenticationToken.getCredentials());System.out.println("认证的用户信息:" + principal + "---" + password);//3.获取数据库中存储的用户信息if(principal.equals("zhangsan")){//3.1数据库中存储的加盐3次迭代的密码String pwdInfo = "b073e9301c412431159e7075340c4c66";//4.创建封装校验逻辑的对象,封装数据返回AuthenticationInfo info = new SimpleAuthenticationInfo(authenticationToken.getPrincipal(),pwdInfo,ByteSource.Util.bytes("salt"),authenticationToken.getPrincipal().toString());return info;}return null;}
}

添加配置信息,让shiro知晓你使用的是自定义的Realm

[main]
#在shiro.ini中添加配置信息
md5CredentialsMatcher=org.apache.shiro.authc.credential.Md5CredentialsMatcher
md5CredentialsMatcher.hashIterations=3
myrealm=com.atguigu.shirotest.MyRealm
myrealm.credentialsMatcher=$md5CredentialsMatcher
securityManager.realms=$myrealm[users]
zhangsan=7174f64b13022acd3c56e2781e098a5f,role1,role2
lisi=l4 [roles]
role1=user:insert,user:select

第三章 与springboot整合

框架整合

1.引入依赖:

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.1.RELEASE</version>
</parent>
<dependencies><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring-boot-web-starter</artifactId><version>1.9.0</version></dependency><!--mybatis-plus--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.0.5</version></dependency><!--mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.46</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
</dependencies>

2.配置文件

# mybatis配置
mybatis-plus:configuration:# 日志log-impl: org.apache.ibatis.logging.stdout.StdOutImplmapper-locations: classpath:mapper/ *.xmlspring:
# 数据库配置datasource:type: com.zaxxer.hikari.HikariDataSourcedriver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/shirodb?characterEncoding=utf-8&useSSL=falsepassword: rootusername: root
# json格式jackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT+8shiro:
# 登录接口loginUrl: /myController/login

3.自定义realm

@Component
public class MyRealm extends AuthorizingRealm{@Autowiredprivate UserService userService;//自定义授权方法@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {return null;}//自定义登录认证方法@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {//1.获取用户身份信息String name = authenticationToken.getPrincipal().toString();//2.调用业务层获取用户信息(数据库)User user = userService.getUserInfoByName(name);//3.非空判断,将数据封装返回if(user != null){AuthenticationInfo info = new SimpleAuthenticationInfo(authenticationToken.getPrincipal(),user.getPwd(),ByteSource.Util.bytes("salt"),authenticationToken.getPrincipal().toString());return info;}return null;}
}

4.配置类

@Slf4j
@Configuration
public class ShiroConfig {@Autowiredprivate MyRealm myRealm;//配置SecurityManager@Beanpublic DefaultWebSecurityManager defaultWebSecurityManager(){//1.创建defaultWebSecurityManager 对象DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();//2.创建加密对象,设置相关属性HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();//2.1 采用md5加密matcher.setHashAlgorithmName("md5");//2.2 迭代加密次数matcher.setHashIterations(3);//3.将加密对象存储到myRealm中myRealm.setCredentialsMatcher(matcher);//4.将myRealm存入defaultWebSecurityManager 对象defaultWebSecurityManager.setRealm(myRealm);//5.返回return defaultWebSecurityManager;}//配置Shiro内置过滤器拦截范围@Beanpublic DefaultShiroFilterChainDefinition shiroFilterChainDefinition(){DefaultShiroFilterChainDefinition defaultShiroFilterChainDefinition = new DefaultShiroFilterChainDefinition();
//        设置不认证就可以访问的资源defaultShiroFilterChainDefinition.addPathDefinition("/myController/userLogin","anon");defaultShiroFilterChainDefinition.addPathDefinition("/login","anon");
//        设置需要进行登录认证的拦截范围defaultShiroFilterChainDefinition.addPathDefinition("/**","authc");return defaultShiroFilterChainDefinition;}
}

5.编写控制类

@Controller
@RequestMapping("myController")
public class MyController{@GetMapping("userLogin")@ResponseBobypublic String userLogin(String name,String pwd){//1.获取subject对象Subject subject = SecurityUtils.getSubject();//2.封装请求数据到tokenAuthenticationToken token = new UsernamePasswordToken(name,pwd);//3.调用login方法进行登录认证try{        subject.login(token);return "登录成功";}catch(AuthenticationException e){e.printStackTrace();System.out.println("登录失败");return "登录失败";}
}

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

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

相关文章

Spring缓存深入解析:@Cacheable的使用详解

摘要&#xff1a;在本文中&#xff0c;我们将深入研究Spring框架中的Cacheable注解。我们会通过详细的Java示例&#xff0c;探讨如何使用这个功能强大的注解来提升应用程序性能。 一、什么是缓存&#xff1f; 在计算机科学中&#xff0c;缓存是一种存储技术&#xff0c;用于保…

LeetCode863. 二叉树中所有距离为 K 的结点(相关话题:深度遍历,广度遍历)

题目描述 给定一个二叉树(具有根结点 root), 一个目标结点 target ,和一个整数值 k 。 返回到目标结点 target 距离为 k 的所有结点的值的列表。 答案可以以 任何顺序 返回。 示例 1: 输入:root = [3,5,1,6,2,0,8,null,null,7,4], target = 5, k = 2 输出:[7,4,1] 解释…

SQL注入之延时注入

文章目录 延时注入是什么&#xff1f;延时注入获取数据库版本号 延时注入是什么&#xff1f; 延时注入就是利用sleep()函数通过if语句判断所写的语句真假&#xff0c;如果为真返回我们想要的东西&#xff08;例如&#xff1a;数据库的长度&#xff0c;数据库的名字等&#xff0…

如何拉取Gitee / GitHub上的Unity项目并成功运行

前言 由于目前大部分人使用的仓库都是Gitee或者是GitHub&#xff0c;包括小编的公司所使用的项目仓库也包括了Gitee&#xff1b;我们需要学习技术栈时都会去百度或者是去GitHub上看看别人的项目观摩学习&#xff0c;可能很多小白在遇到拉取代码时出现各种问题&#xff0c;或者…

智能安全帽_防抖视频定位智能安全帽头盔

智能安全帽具备出色的性能、超低功耗、广范围覆盖和简单的外围电路等优势&#xff0c;同时还拥有丰富的外部接口。它支持移动/联通/电信的4G5G网络&#xff0c;涵盖了LTE-TDD频段(B34/B38/B39/B40/B41)、LTE-FDD频段(B1/B3/B5/B8)、WCDMA频段(B1/B5/B8)、TD-SCDMA频段(B34/B39)…

二、11.系统交互

fork 函数原型是 pid_t fork(void&#xff09;&#xff0c;返回值是数字&#xff0c;该数字有可能是子进程的 pid &#xff0c;有可能是 0&#xff0c;也有可能是-1 。 1个函数有 3 种返回值&#xff0c;这是为什么呢&#xff1f;可能的原因是 Linux 中没有获取子进程 pid 的方…

R语言机器学习方法在生态经济学领域

近年来&#xff0c;人工智能领域已经取得突破性进展&#xff0c;对经济社会各个领域都产生了重大影响&#xff0c;结合了统计学、数据科学和计算机科学的机器学习是人工智能的主流方向之一&#xff0c;目前也在飞快的融入计量经济学研究。表面上机器学习通常使用大数据&#xf…

从聚类(Clustering)到异常检测(Anomaly Detection):常用无监督学习方法的优缺点

一、引言 无监督学习是机器学习的一种重要方法&#xff0c;与有监督学习不同&#xff0c;它使用未标记的数据进行训练和模式发现。无监督学习在数据分析中扮演着重要的角色&#xff0c;能够从数据中发现隐藏的模式、结构和关联关系&#xff0c;为问题解决和决策提供有益的信息。…

static相关知识点详解

文章目录 一. 修饰成员变量二. 修饰成员方法三. 修饰代码块四. 修饰类 一. 修饰成员变量 static 修饰的成员变量&#xff0c;称为静态成员变量&#xff0c;该变量不属于某个具体的对象&#xff0c;是所有对象所共享的。 public class Student {private String name;private sta…

【了解一下常见的设计模式】

文章目录 了解一下常用的设计模式(工厂、包装、关系)导语设计模式辨析系列 工厂篇工厂什么是工厂简单工厂「模式」&#xff08;Simple Factory「Pattern」&#xff09;简单工厂代码示例&#xff1a;简单计算器优点&#xff1a;缺点&#xff1a; 静态工厂模式特点&#xff1a; 工…

如何在网页下载腾讯视频为本地MP4格式

1.打开腾讯视频官网地址 腾讯视频 2.搜索你想要下载的视频 3. 点击分享,选择复制通用代码 <iframe frameborder="0" src="ht

Pixar、Adobe 和苹果等成立 OpenUSD 联盟推行 3D 内容开放标准

导读Pixar、Adobe、Apple、Autodesk 与 NVIDIA 联手 Linux 基金会旗下的联合开发基金会&#xff08;JDF&#xff09;宣布建立 OpenUSD 联盟&#xff08;AOUSD&#xff09;以推行 Pixar 创建的通用场景描述技术的标准化、开发、进化和发展。 联盟寻求通过推进开放式通用场景描述…

redisDb底层结构

redis数据库 redis在初始化服务器时&#xff0c;会根据服务器状态的dbnum属性来决定创建多少个数据库&#xff0c;dbnum属性的值由服务器配置的database选项决定&#xff0c;默认情况下为16&#xff0c;redisServer结构如下&#xff1a; struct redisServer {// ...//一个数组…

初探科研 | 第一次科研经历

1 . 自己的experiences 自己大二下学期中比较幸运加入到科研组里&#xff0c;做的方向是3D人体姿态估计&#xff0c;不过由于是一个全新领域&#xff0c;基本也是自己这个小白探索&#xff0c;所以成果甚微。在八月初由于各种原因退出了组&#xff0c;但是在这期间收获还是蛮多…

全网最全ArrayList底层原理实现

1. ArrayList集合底层数据结构 1. ArrayList集合介绍 ArrayList是实现了List接口的动态数组&#xff0c;所谓动态数组就是他的大小是可变的。实现了所有可选列表操作&#xff0c;并允许包括Null在内的所有元素。除了实现 List 接口外&#xff0c;此类还提供一些方法来操作内部…

如何将应用程序发布到 App Store

憧憬blog主页 在强者的眼中&#xff0c;没有最好&#xff0c;只有更好。我们是移动开发领域的优质创作者&#xff0c;同时也是阿里云专家博主。 ✨ 关注我们的主页&#xff0c;探索iOS开发的无限可能&#xff01; &#x1f525;我们与您分享最新的技术洞察和实战经验&#xff0…

伦敦金短线好还是长线好

在伦敦金投之中&#xff0c;长期有一个争论很久的问题&#xff0c;那就是伦敦金投资究竟是长线好还是短线好&#xff1f;不同的投资者对这个问题有不同的看法&#xff0c;一般认为&#xff0c;伦敦金投资比较适合短线交易。笔者也将讨论这个问题&#xff0c;看看伦敦金投资是不…

【官方中文文档】Mybatis-Spring #使用 SqlSession

使用 SqlSession 在 MyBatis 中&#xff0c;你可以使用 SqlSessionFactory 来创建 SqlSession。 一旦你获得一个 session 之后&#xff0c;你可以使用它来执行映射了的语句&#xff0c;提交或回滚连接&#xff0c;最后&#xff0c;当不再需要它的时候&#xff0c;你可以关闭 s…

MinIO线上扩容实战

硬件投入肯定是随着业务的增长而增长&#xff0c;这就要求中间件平台必须提供水平伸缩机制&#xff0c;MinIO对象存储服务也不例外&#xff0c;本文就详细介绍MinIO的扩容。 Minio支持通过增加新的Server Pool来扩容老的集群。每个Server Pool都是一个相对独立的故障域&#x…

​深度解析温湿度监控系统环境对档案存储库房的影响

深度解析温湿度监控系统环境对档案存储库房的影响 &#xff08;一&#xff09;高温高湿环境对档案材料的影响 1、库房高温高湿会使一些档案纸张材料中耐热性较差的字迹产生油渗扩散褪变等现象而导致字迹模糊不清&#xff0c;会加速纸张中残留的有害化学物质对纤维素的破坏潮湿…