Shiro第二篇【介绍Shiro、认证流程、自定义realm、自定义realm支持md5】
什么是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】相关推荐
- [游戏开发]Python打表工具系列 [第二篇] [打表流程描简述]
[上一篇链接] [游戏开发]Python打表工具系列 [第一篇][IDE开发环境部署] VSCode Python环境调试_Little丶Seven的博客-CSDN博客 [前言] 第二篇文章是对流程的 ...
- Spring Security Oauth2 认证流程
1.本文介绍的认证流程范围 本文主要对从用户发起获取token的请求(/oauth/token),到请求结束返回token中间经过的几个关键点进行说明. 2.认证会用到的相关请求 注:所有请求均为po ...
- Kerberos认证流程详解
Kerberos是诞生于上个世纪90年代的计算机认证协议,被广泛应用于各大操作系统和Hadoop生态系统中.了解Kerberos认证的流程将有助于解决Hadoop集群中的安全配置过程中的问题.为此,本 ...
- Shiro框架:Shiro简介、登陆认证入门程序、认证执行流程、使用自定义Realm进行登陆认证、Shiro的MD5散列算法
一.Shiro介绍: 1.什么是shiro: (1)shiro是apache的一个开源框架,是一个权限管理的框架,实现用户认证.用户授权. (2)spring中有spring security,是一个 ...
- Shiro介绍及主要流程
Shiro介绍及主要流程 什么是Shiro Apache Shiro是一个强大且灵活的开源安全框架,易于使用且好理解,撇开了搭建安全框架时的复杂性. Shiro可以帮助我们做以下几件事: 认证使用者的 ...
- shiro表单登录认证及退出(自定义form认证器)
博主地址:http://blog.csdn.net/zcl_love_wx 注意:此文是基于springMVC框架的,所以关于springMVC的配置这里不说,后面有时间专门写一个shiro整合spr ...
- shiro认证与授权:自定义realm
[main] #声明realm permReam=cn.learn.shiro.PermissionRealm #注册realm到securityManager中 securityManager.re ...
- shiro学习(4):shiro认证流程
Shiro登录校验流程实现与分析 什么是Shiro Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码和会话管理.使用Shiro的易于理解的API,您可以快速.轻松地 ...
- 详解Shiro认证流程
详解Shiro认证流程 isAccessAllowed Subject在如何得到? resolveSession doCreateSubject save(Subject subject) isAut ...
最新文章
- 多个模型在测试集上的Accuracy以及AUC指标可视化对比实战
- 开启报名 | 青源 Salon 第 1 期:强化学习专场,报告,海报,激辩,这是年轻人的会场
- CSS导航栏实例详解
- ***入门基础知识(超全)
- HTML 5 Web Socket:下一次Web通信革命揭幕,互联网营销
- 剑指Offer——和为s的两个数字
- 蓝桥杯-基础练习 十六进制转八进制
- MRTG 监控主机流量
- python网络爬虫实践_第18,Python网络爬虫实践(1)
- Android Studio 红米3 一直运行或者debug不成功,提示 Failed to establish session 解决方案
- JavaScript 函数参数默认值
- Centos6 安装可视化界面
- Java程序员从笨鸟到菜鸟(三)算法笔试题
- 学 stm 32 单片机
- python绘制语谱图(不掉包实现)
- 山东省2013高职分数线
- 大一上学期C++课程设计——学生成绩管理系统(QT项目)
- docker学习(十二)docker secret 的使用
- RabbitMQ核心概念及基础API应用
- wchar_t的使用