Shiro入门—认证
- 什么是shiro
shiro是apache的一个开源权限管理框架,实现用户认证、用户授权。
spring中有spring security (原名Acegi),是一个权限框架,它和spring依赖过于紧密,没有shiro使用简单。
shiro不依赖于spring,shiro不仅可以实现 web应用的权限管理,还可以实现c/s系统,分布式系统权限管理,shiro属于轻量框架,使用shiro实现系统权限管理,可以有效提高开发效率,降低开发成本。
先看一下认证和授权时的关键对象:
subject:主体。理解为用户,可能是程序,要去访问系统的资源,系统需要对subject进行身份认证。
principal:身份信息。通常是唯一的,一个主体还有多个身份信息,但是都有一个主身份信息(primary principal)
credential:凭证信息。可以是密码 、证书、指纹。
主体在进行身份认证时需要提供身份信息和凭证信息。 - shiro架构
subject:主体。可以是用户也可以是程序,主体访问系统,系统对主体进行认证、授权。
securityManager:安全管理器。主体进行认证和授权都 是通过securityManager进行。
authenticator:认证器。主体进行认证最终通过authenticator进行的。
authorizer:授权器。主体进行授权最终通过authorizer进行的。
sessionManager:web应用中一般是用web容器(如Tomcat)对session进行管理,shiro也提供了一套session管理的方式。
SessionDao: 通过SessionDao管理session数据,针对个性化的session数据存储需要使用sessionDao。
cache Manager:缓存管理器。主要对session和授权数据进行缓存,比如将授权数据通过cacheManager进行缓存管理,和ehcache整合对缓存数据进行管理。
realm:域,领域。相当于数据源,通过realm存取认证、授权相关数据。
注意:在realm中存储授权和认证的逻辑。
cryptography:密码管理。提供了一套加密/解密的组件。比如提供常用的散列、加/解密等功能(如Md5)。 - shiro认证流程
- shiro认证入门程序
/*** @Description 测试登录登出* @Author 刘俊重* @date 2017年8月1日 * @return void*/@Testpublic void testLoginAndLogout(){//通过ini配置文件创建SecurityManager工厂Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-first.ini");//使用SecurityManagerFactory获取SecurityManager对象SecurityManager securityManager = factory.getInstance();//将SecurityManager设置在当前运行环境中SecurityUtils.setSecurityManager(securityManager);//从SecurityUtils中创建一个subject(主体)Subject subject = SecurityUtils.getSubject();//在认证提交前准备tokenUsernamePasswordToken token = new UsernamePasswordToken("zhangsan","111111");//提交主体认证try {subject.login(token);} catch (AuthenticationException e) {e.printStackTrace();}//获取认证结果boolean result = subject.isAuthenticated();System.out.println("是否认证通过"+result);//退出操作subject.logout();//再次获取认证结果boolean againResult = subject.isAuthenticated();System.out.println("第二次认证结果"+againResult);}
通过shiro-first.ini配置文件创建SecurityManager工厂,配置文件代码如下:
#对用户信息进行配置
[users]
#用户账号和密码
zhangsan=111111
lisi=22222
上面程序的执行流程如下:
1通过ini配置文件创建securityManager
2调用subject.login方法主体提交认证,提交的token
3securityManager进行认证,securityManager最终由ModularRealmAuthenticator进行认证。
4ModularRealmAuthenticator调用IniRealm(给realm传入token) 去ini配置文件中查询用户信息
5IniRealm根据输入的token(UsernamePasswordToken)从 shiro-first.ini查询用户信息,根据账号查询用户信息(账号和密码)
如果查询到用户信息,就给ModularRealmAuthenticator返回用户信息(账号和密码)
如果查询不到,就给ModularRealmAuthenticator返回null
6ModularRealmAuthenticator接收IniRealm返回Authentication认证信息
如果返回的认证信息是null,ModularRealmAuthenticator抛出异常(org.apache.shiro.authc.UnknownAccountException)
如果返回的认证信息不是null(说明inirealm找到了用户),对IniRealm返回用户密码 (在ini文件中存在)和 token中的密码 进行对比,如果不一致抛出异常(org.apache.shiro.authc.IncorrectCredentialsException)
5. 自定义Realm
实际开发需要realm从数据库中查询用户信息。所以需要自定义Realm。
package com.catchu.realm;
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.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
/*** @author 刘俊重* @Description 自定义Realm* @date 2017年8月1日*/
public class CustomRealm extends AuthorizingRealm {/*** @Description 用于授权* @Author 刘俊重* @date 2017年8月1日*/@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {return null;}/*** @Description 用于认证* @Author 刘俊重* @date 2017年8月1日*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { //从token获取principal(身份信息)String principal = (String) token.getPrincipal();//模拟从数据库中获取到了credentials(授权信息)String credentials = "111111";SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(principal, credentials, getName());return simpleAuthenticationInfo;}
}
单元测试代码如下:
/*** @Description 测试自定义realm* @Author 刘俊重* @date 2017年8月1日 * @return void*/@Testpublic void testCustomRealm(){//生成SecurityManager工厂Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-realm.ini");//使用SecurityManager工厂获取SecurityManagerSecurityManager securityManager = factory.getInstance();//将Securitymanager设置在当前运行环境中SecurityUtils.setSecurityManager(securityManager);//从SecurityUtils中生成subject(主体)Subject subject = SecurityUtils.getSubject();//在认证前准备token,将来由用户输入UsernamePasswordToken token = new UsernamePasswordToken("zhangsan","111111");//提交认证try {subject.login(token);} catch (AuthenticationException e) {e.printStackTrace();}//获取授权结果boolean result = subject.isAuthenticated();System.out.println("认证结果:"+result);}
shiro-realm.ini配置文件如下:
[main]
#自定义 realm
customRealm=com.catchu.realm.CustomRealm
#将realm设置到securityManager,相当 于spring中注入
securityManager.realms=$customRealm
6.md5散列算法和盐
实际开发中通常需要对密码进行散列,常用的有md5、sha。建议对md5进行散列时加salt(盐),进行加密相当于对原始密码+盐进行散列。
正常使用时散列方法:
在程序中对原始密码+盐进行散列,将散列值和盐存储到数据库中。
在进行密码对比时,使用相同方法,将输入密码+盐进行散列,与数据库存储的散列值进行比对。
import org.apache.shiro.crypto.hash.Md5Hash;
/*** @author 刘俊重* @Description md5散列测试* @date 2017年8月2日*/
public class Md5Test {public static void main(String[] args) {//原始密码String source = "111111";//盐String salt = "qwerty";//散列次数(就是进行了几次md5加密)int hashIterations = 1;//散列一次的值:f3694f162729b7d0254c6e40260bf15c//散列两次的值:36f2dfa24d0a9fa97276abbe13e596fcMd5Hash md5Hash = new Md5Hash(source, salt, hashIterations);System.out.println("md5散列后的值:"+md5Hash.toString());}
}
7.自定义Realm支持Md5散列
自定义Realm如下:
package com.catchu.realm;
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.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
/*** @author 刘俊重* @Description 自定义Ream实现md5散列加密* @date 2017年8月2日*/
public class CustomRealmMd5 extends AuthorizingRealm {/*** @Description 用于授权* @Author 刘俊重* @date 2017年8月2日*/@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {// TODO Auto-generated method stubreturn null;}/*** @Description 用于认证* @Author 刘俊重* @date 2017年8月2日*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { //从token中获取principal(身份信息),在这里指的就是用户名String principal = (String) token.getPrincipal(); //模拟从数据库中获取到了credentials(授权信息),在这里值的是密码在数据库中的散列值String credentials = "f3694f162729b7d0254c6e40260bf15c";//从数据库中获取salt(盐)String salt = "qwerty";SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(principal, credentials, ByteSource.Util.bytes(salt),getName());return simpleAuthenticationInfo;}
}
单元测试代码如下:
/*** @Description 测试自定义realm,Md5版* @Author 刘俊重* @date 2017年8月2日 * @return void*/@Testpublic void testCustomRealmMd5(){//根据ini配置文件生成SecurityManager工厂类Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-realm-md5.ini"); //生成SecurityManager(安全管理器)SecurityManager securityManager = factory.getInstance();//将安全管理器设置在当前运行环境中SecurityUtils.setSecurityManager(securityManager);//从SecurityUtils中生成subject(主体)Subject subject = SecurityUtils.getSubject();//在认证前准备token(令牌),正式环境中由用户输入UsernamePasswordToken token = new UsernamePasswordToken("zhangsan","111111");//提交认证try {subject.login(token);} catch (AuthenticationException e) {e.printStackTrace();}//是否认证通过boolean isAuthenticated = subject.isAuthenticated();System.out.println("是否认证通过"+isAuthenticated);}
其中生成SecurityManager工厂类的配置文件shiro-realm-md5.ini如下:
[main]
#定义凭证匹配器
credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
#散列算法
credentialsMatcher.hashAlgorithmName=md5
#散列次数
credentialsMatcher.hashIterations=1
#将凭证匹配器设置到realm
customRealm=com.catchu.realm.CustomRealmMd5
customRealm.credentialsMatcher=$credentialsMatcher
securityManager.realms=$customRealm
8.引入jar
上面忘记说了,与其它java开源框架类似,将shiro的jar包加入项目就可以使用shiro提供的功能了。shiro-core是核心包必须选用,还提供了与web整合的shiro-web、与spring整合的shiro-spring、与任务调度quartz整合的shiro-quartz等,下边是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-all包括shiro所有的包:
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-all</artifactId><version>1.2.3</version></dependency>
参考代码:http://download.csdn.net/detail/u014532775/9920343
Shiro入门—认证相关推荐
- Shiro身份认证---转
目录 1. Shro的概念 2. Shiro的简单身份认证实现 3. Shiro与spring对身份认证的实现 前言: Shiro 可以非常容易的开发出足够好的应用,其不仅可以用在 JavaSE 环境 ...
- Apache Shiro入门
Apache Shiro入门 @(Shiro)[shiro,安全框架] Apache Shiro入门 Apache Shiro基本概述 Apache Shiro基本概念 使用Shiro能做什么 Shi ...
- Shiro 入门笔记,整合SpringBoot,Redis
Shiro 入门笔记 视频地址:https://www.bilibili.com/video/BV1uz4y197Zm 感谢编程不良人的教程 1. 权限管理 权限管理包括用户 身份认证 和 授权 两部 ...
- Shiro入门以及Shiro与web整合
标题Shiro入门以及Shiro与web整合 Shiro框架 - 什么是Shiro? Apache shiro是一个强大,易用的java安全框架执行身份认证,授权,密码和会话管理. Shiro框架的核 ...
- JavaWeb:shiro入门小案例
学习原因:刚接触Javaweb的时候懂的很少(当然现在也不多),所以开发一个小项目都是自己从头写到尾,从登录界面一直到数据库,当时想以后开发要是都这么写那不是很枯燥?!-知道后来团队开发,接触的开发人 ...
- Shiro入门这篇就够了【Shiro的基础知识、回顾URL拦截】
前言 本文主要讲解的知识点有以下: 权限管理的基础知识 模型 粗粒度和细粒度的概念 回顾URL拦截的实现 Shiro的介绍与简单入门 一.Shiro基础知识 在学习Shiro这个框架之前,首先我们要先 ...
- Shiro实现认证_ini
1,基本概念 1,身份验证 即在应用中谁能证明他就是他本人.一般提供如他们的身份ID 一些标识信息来表明他就是他本人, 如提供身份证,用户名/密码来证明. 在 shiro 中,用户需要提供princ ...
- authc过滤器 shiro_使用Shiro实现认证和授权(基于SpringBoot)
Apache Shiro是一个功能强大且易于使用的Java安全框架,它为开发人员提供了一种直观,全面的身份验证,授权,加密和会话管理解决方案.下面是在SpringBoot中使用Shiro进行认证和授权 ...
- springboot+mybatis整合shiro——登录认证和权限控制
引依赖 shiro-all包含shiro所有的包.shiro-core是核心包.shiro-web是与web整合.shiro-spring是与spring整合.shiro-ehcache是与EHCac ...
最新文章
- apache 重定向tomcat端口_Tomcat
- 百度前端技术学院2017学习总结
- stm8s开发(二) GPIO的使用:点亮LED!
- BZOJ4066: 简单题
- 使用jupyter notebook连接服务器进行远程写代码
- Syntax error, parameterized types are only available if source level is 1.5 or greater
- F5 root密码恢复
- c语言代码格式的简单介绍
- IIS服务的命令行方式重启命令
- 破解计算机win7管理员密码,教你win7旗舰版怎么破密码
- 教程篇(7.0) 01. 介绍FortiClient和FortiClient EMS ❀ FortiClient EMS ❀ Fortinet 网络安全专家 NSE 5
- MyHandler.h对消息accu的处理
- B端产品运营:学习笔记
- linux 下执行shutdown.sh命令不能关闭tomcat进程的解决方法
- 我学编程全靠B站了,真香(第一期)
- ubuntu 为可执行程序创建启动图标
- oracle中创建事件的作用,Oracle常见等待事件说明(二)-direct path read/write
- USACO Section 1.2PROB Miking Cows
- Google App Engine+GAppProxy 架设个人代理服务器
- 鸿蒙见面会为什么没选在深圳,全军出击!华为智选发布16款新品:鸿蒙分布式技术来了近日,华...