什么是Shiro

shiro是apache的一个开源框架,是一个权限管理的框架,实现 用户认证、用户授权

spring中有spring security (原名Acegi),是一个权限框架,它和spring依赖过于紧密,没有shiro使用简单。
shiro不依赖于spring,shiro不仅可以实现 web应用的权限管理,还可以实现c/s系统,分布式系统权限管理,shiro属于轻量框架,越来越多企业项目开始使用shiro。

Shiro架构:

  • subject:主体,可以是用户也可以是程序,主体要访问系统,系统需要对主体进行认证、授权。
  • securityManager:安全管理器,主体进行认证和授权都 是通过securityManager进行。
  • authenticator:认证器,主体进行认证最终通过authenticator进行的。
  • authorizer:授权器,主体进行授权最终通过authorizer进行的。
  • sessionManager:web应用中一般是用web容器对session进行管理,shiro也提供一套session管理的方式。
  • SessionDao: 通过SessionDao管理session数据,针对个性化的session数据存储需要使用sessionDao。
  • cache Manager:缓存管理器,主要对session和授权数据进行缓存,比如将授权数据通过cacheManager进行缓存管理,和ehcache整合对缓存数据进行管理。
  • realm:域,领域,相当于数据源,通过realm存取认证、授权相关数据。

cryptography:密码管理,提供了一套加密/解密的组件,方便开发。比如提供常用的散列、加/解密等功能。

  • 比如md5散列算法。

为什么使用Shiro

我们在使用URL拦截的时候,要将所有的URL都配置起来,繁琐、不易维护

而我们的Shiro实现系统的权限管理,有效提高开发效率,从而降低开发成本。

Shiro认证

导入jar包

我们使用的是Maven的坐标就行了

<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>1.2.3</version></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-web</artifactId><version>1.2.3</version></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>1.2.3</version></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-ehcache</artifactId><version>1.2.3</version></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-quartz</artifactId><version>1.2.3</version></dependency>

当然了,我们也可以把Shiro相关的jar包全部导入进去


<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-all</artifactId><version>1.2.3</version>
</dependency>

Shiro认证流程

通过配置文件创建工厂

// 用户登陆和退出@Testpublic void testLoginAndLogout() {// 创建securityManager工厂,通过ini配置文件创建securityManager工厂Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-first.ini");// 创建SecurityManagerSecurityManager securityManager = factory.getInstance();// 将securityManager设置当前的运行环境中SecurityUtils.setSecurityManager(securityManager);// 从SecurityUtils里边创建一个subjectSubject subject = SecurityUtils.getSubject();// 在认证提交前准备token(令牌)// 这里的账号和密码 将来是由用户输入进去UsernamePasswordToken token = new UsernamePasswordToken("zhangsan","111111");try {// 执行认证提交subject.login(token);} catch (AuthenticationException e) {// TODO Auto-generated catch blocke.printStackTrace();}// 是否认证通过boolean isAuthenticated = subject.isAuthenticated();System.out.println("是否认证通过:" + isAuthenticated);// 退出操作subject.logout();// 是否认证通过isAuthenticated = subject.isAuthenticated();System.out.println("是否认证通过:" + isAuthenticated);}

小结

ModularRealmAuthenticator作用进行认证,需要调用realm查询用户信息(在数据库中存在用户信息)
ModularRealmAuthenticator进行密码对比(认证过程)。
realm:需要根据token中的身份信息去查询数据库(入门程序使用ini配置文件),如果查到用户返回认证信息,如果查询不到返回null

自定义realm

从第一个认证程序我们可以看见,我们所说的流程,是认证器去找realm去查询我们相对应的数据。而默认的realm是直接去与配置文件来比对的,一般地,我们在开发中都是让realm去数据库中比对。
因此,我们需要自定义realm


public class CustomRealm extends AuthorizingRealm {// 设置realm的名称@Overridepublic void setName(String name) {super.setName("customRealm");}// 用于认证@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {// token是用户输入的// 第一步从token中取出身份信息String userCode = (String) token.getPrincipal();// 第二步:根据用户输入的userCode从数据库查询// ....// 如果查询不到返回null//数据库中用户账号是zhangsansan/*if(!userCode.equals("zhangsansan")){//return null;}*/// 模拟从数据库查询到密码String password = "111112";// 如果查询到返回认证信息AuthenticationInfoSimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(userCode, password, this.getName());return simpleAuthenticationInfo;}// 用于授权@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {// TODO Auto-generated method stubreturn null;}}

配置realm

需要在shiro-realm.ini配置realm注入到securityManager中。

测试自定义realm

同上边的入门程序,需要更改ini配置文件路径:


同上边的入门程序,需要更改ini配置文件路径:
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-realm.ini");

散列算法

我们如果知道md5,我们就会知道md5是不可逆的,但是如果设置了一些安全性比较低的密码:111111…即时是不可逆的,但还是可以通过暴力算法来得到md5对应的明文…

建议对md5进行散列时加salt(盐),进行加密相当 于对原始密码+盐进行散列。\

正常使用时散列方法:

  • 在程序中对原始密码+盐进行散列,将散列值存储到数据库中,并且还要将盐也要存储在数据库中。

测试:


public class MD5Test {public static void main(String[] args) {//原始 密码 String source = "111111";//盐String salt = "qwerty";//散列次数int hashIterations = 2;//上边散列1次:f3694f162729b7d0254c6e40260bf15c//上边散列2次:36f2dfa24d0a9fa97276abbe13e596fc//构造方法中://第一个参数:明文,原始密码 //第二个参数:盐,通过使用随机数//第三个参数:散列的次数,比如散列两次,相当 于md5(md5(''))Md5Hash md5Hash = new Md5Hash(source, salt, hashIterations);String password_md5 =  md5Hash.toString();System.out.println(password_md5);//第一个参数:散列算法 SimpleHash simpleHash = new SimpleHash("md5", source, salt, hashIterations);System.out.println(simpleHash.toString());}}

自定义realm支持md5

自定义realm


public class CustomRealmMd5 extends AuthorizingRealm {// 设置realm的名称@Overridepublic void setName(String name) {super.setName("customRealmMd5");}// 用于认证@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {// token是用户输入的// 第一步从token中取出身份信息String userCode = (String) token.getPrincipal();// 第二步:根据用户输入的userCode从数据库查询// ....// 如果查询不到返回null// 数据库中用户账号是zhangsansan/** if(!userCode.equals("zhangsansan")){// return null; }*/// 模拟从数据库查询到密码,散列值String password = "f3694f162729b7d0254c6e40260bf15c";// 从数据库获取saltString salt = "qwerty";//上边散列值和盐对应的明文:111111// 如果查询到返回认证信息AuthenticationInfoSimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(userCode, password, ByteSource.Util.bytes(salt), this.getName());return simpleAuthenticationInfo;}// 用于授权@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {// TODO Auto-generated method stubreturn null;}}

配置文件:

测试:


// 自定义realm实现散列值匹配@Testpublic void testCustomRealmMd5() {// 创建securityManager工厂,通过ini配置文件创建securityManager工厂Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-realm-md5.ini");// 创建SecurityManagerSecurityManager securityManager = factory.getInstance();// 将securityManager设置当前的运行环境中SecurityUtils.setSecurityManager(securityManager);// 从SecurityUtils里边创建一个subjectSubject subject = SecurityUtils.getSubject();// 在认证提交前准备token(令牌)// 这里的账号和密码 将来是由用户输入进去UsernamePasswordToken token = new UsernamePasswordToken("zhangsan","222222");try {// 执行认证提交subject.login(token);} catch (AuthenticationException e) {// TODO Auto-generated catch blocke.printStackTrace();}// 是否认证通过boolean isAuthenticated = subject.isAuthenticated();System.out.println("是否认证通过:" + isAuthenticated);}

<script type="text/javascript"> $(function () { $('pre.prettyprint code').each(function () { var lines = $(this).text().split('\n').length; var $numbering = $('<ul/>').addClass('pre-numbering').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($('<li/>').text(i)); }; $numbering.fadeIn(1700); }); }); </script>

Shiro第二篇【介绍Shiro、认证流程、自定义realm、自定义realm支持md5】相关推荐

  1. [游戏开发]Python打表工具系列 [第二篇] [打表流程描简述]

    [上一篇链接] [游戏开发]Python打表工具系列 [第一篇][IDE开发环境部署] VSCode Python环境调试_Little丶Seven的博客-CSDN博客 [前言] 第二篇文章是对流程的 ...

  2. Spring Security Oauth2 认证流程

    1.本文介绍的认证流程范围 本文主要对从用户发起获取token的请求(/oauth/token),到请求结束返回token中间经过的几个关键点进行说明. 2.认证会用到的相关请求 注:所有请求均为po ...

  3. Kerberos认证流程详解

    Kerberos是诞生于上个世纪90年代的计算机认证协议,被广泛应用于各大操作系统和Hadoop生态系统中.了解Kerberos认证的流程将有助于解决Hadoop集群中的安全配置过程中的问题.为此,本 ...

  4. Shiro框架:Shiro简介、登陆认证入门程序、认证执行流程、使用自定义Realm进行登陆认证、Shiro的MD5散列算法

    一.Shiro介绍: 1.什么是shiro: (1)shiro是apache的一个开源框架,是一个权限管理的框架,实现用户认证.用户授权. (2)spring中有spring security,是一个 ...

  5. Shiro介绍及主要流程

    Shiro介绍及主要流程 什么是Shiro Apache Shiro是一个强大且灵活的开源安全框架,易于使用且好理解,撇开了搭建安全框架时的复杂性. Shiro可以帮助我们做以下几件事: 认证使用者的 ...

  6. shiro表单登录认证及退出(自定义form认证器)

    博主地址:http://blog.csdn.net/zcl_love_wx 注意:此文是基于springMVC框架的,所以关于springMVC的配置这里不说,后面有时间专门写一个shiro整合spr ...

  7. shiro认证与授权:自定义realm

    [main] #声明realm permReam=cn.learn.shiro.PermissionRealm #注册realm到securityManager中 securityManager.re ...

  8. shiro学习(4):shiro认证流程

    Shiro登录校验流程实现与分析 什么是Shiro Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码和会话管理.使用Shiro的易于理解的API,您可以快速.轻松地 ...

  9. 详解Shiro认证流程

    详解Shiro认证流程 isAccessAllowed Subject在如何得到? resolveSession doCreateSubject save(Subject subject) isAut ...

最新文章

  1. 多个模型在测试集上的Accuracy以及AUC指标可视化对比实战
  2. 开启报名 | 青源 Salon 第 1 期:强化学习专场,报告,海报,激辩,这是年轻人的会场
  3. CSS导航栏实例详解
  4. ***入门基础知识(超全)
  5. HTML 5 Web Socket:下一次Web通信革命揭幕,互联网营销
  6. 剑指Offer——和为s的两个数字
  7. 蓝桥杯-基础练习 十六进制转八进制
  8. MRTG 监控主机流量
  9. python网络爬虫实践_第18,Python网络爬虫实践(1)
  10. Android Studio 红米3 一直运行或者debug不成功,提示 Failed to establish session 解决方案
  11. JavaScript 函数参数默认值
  12. Centos6 安装可视化界面
  13. Java程序员从笨鸟到菜鸟(三)算法笔试题
  14. 学 stm 32 单片机
  15. python绘制语谱图(不掉包实现)
  16. 山东省2013高职分数线
  17. 大一上学期C++课程设计——学生成绩管理系统(QT项目)
  18. docker学习(十二)docker secret 的使用
  19. RabbitMQ核心概念及基础API应用
  20. wchar_t的使用

热门文章

  1. 浅谈未来跨境电商发展的新趋势?
  2. 2013 编程之美挑战赛 仙剑5前传之璇光殿
  3. 每个人应该怎样保护我们得隐私数据
  4. mysql如何做直播_一个新手如何做直播
  5. 聊聊ip与mac地址之间那些事
  6. JavaScript开发工具列表
  7. 彻底卸载Office
  8. 使用5G的好处你明白有哪些吗?
  9. 【第169期】想做游戏策划,我建议学学与游戏无关的东西
  10. 2021届java实习生岗位要求