1. 什么是shiro
    shiro是apache的一个开源权限管理框架,实现用户认证、用户授权。
    spring中有spring security (原名Acegi),是一个权限框架,它和spring依赖过于紧密,没有shiro使用简单。
    shiro不依赖于spring,shiro不仅可以实现 web应用的权限管理,还可以实现c/s系统,分布式系统权限管理,shiro属于轻量框架,使用shiro实现系统权限管理,可以有效提高开发效率,降低开发成本。
    先看一下认证和授权时的关键对象:
    subject:主体。理解为用户,可能是程序,要去访问系统的资源,系统需要对subject进行身份认证。
    principal:身份信息。通常是唯一的,一个主体还有多个身份信息,但是都有一个主身份信息(primary principal)
    credential:凭证信息。可以是密码 、证书、指纹。
    主体在进行身份认证时需要提供身份信息和凭证信息。
  2. 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)。
  3. shiro认证流程
  4. 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入门—认证相关推荐

  1. Shiro身份认证---转

    目录 1. Shro的概念 2. Shiro的简单身份认证实现 3. Shiro与spring对身份认证的实现 前言: Shiro 可以非常容易的开发出足够好的应用,其不仅可以用在 JavaSE 环境 ...

  2. Apache Shiro入门

    Apache Shiro入门 @(Shiro)[shiro,安全框架] Apache Shiro入门 Apache Shiro基本概述 Apache Shiro基本概念 使用Shiro能做什么 Shi ...

  3. Shiro 入门笔记,整合SpringBoot,Redis

    Shiro 入门笔记 视频地址:https://www.bilibili.com/video/BV1uz4y197Zm 感谢编程不良人的教程 1. 权限管理 权限管理包括用户 身份认证 和 授权 两部 ...

  4. Shiro入门以及Shiro与web整合

    标题Shiro入门以及Shiro与web整合 Shiro框架 - 什么是Shiro? Apache shiro是一个强大,易用的java安全框架执行身份认证,授权,密码和会话管理. Shiro框架的核 ...

  5. JavaWeb:shiro入门小案例

    学习原因:刚接触Javaweb的时候懂的很少(当然现在也不多),所以开发一个小项目都是自己从头写到尾,从登录界面一直到数据库,当时想以后开发要是都这么写那不是很枯燥?!-知道后来团队开发,接触的开发人 ...

  6. Shiro入门这篇就够了【Shiro的基础知识、回顾URL拦截】

    前言 本文主要讲解的知识点有以下: 权限管理的基础知识 模型 粗粒度和细粒度的概念 回顾URL拦截的实现 Shiro的介绍与简单入门 一.Shiro基础知识 在学习Shiro这个框架之前,首先我们要先 ...

  7. Shiro实现认证_ini

     1,基本概念 1,身份验证 即在应用中谁能证明他就是他本人.一般提供如他们的身份ID 一些标识信息来表明他就是他本人, 如提供身份证,用户名/密码来证明. 在 shiro 中,用户需要提供princ ...

  8. authc过滤器 shiro_使用Shiro实现认证和授权(基于SpringBoot)

    Apache Shiro是一个功能强大且易于使用的Java安全框架,它为开发人员提供了一种直观,全面的身份验证,授权,加密和会话管理解决方案.下面是在SpringBoot中使用Shiro进行认证和授权 ...

  9. springboot+mybatis整合shiro——登录认证和权限控制

    引依赖 shiro-all包含shiro所有的包.shiro-core是核心包.shiro-web是与web整合.shiro-spring是与spring整合.shiro-ehcache是与EHCac ...

最新文章

  1. apache 重定向tomcat端口_Tomcat
  2. 百度前端技术学院2017学习总结
  3. stm8s开发(二) GPIO的使用:点亮LED!
  4. BZOJ4066: 简单题
  5. 使用jupyter notebook连接服务器进行远程写代码
  6. Syntax error, parameterized types are only available if source level is 1.5 or greater
  7. F5 root密码恢复
  8. c语言代码格式的简单介绍
  9. IIS服务的命令行方式重启命令
  10. 破解计算机win7管理员密码,教你win7旗舰版怎么破密码
  11. 教程篇(7.0) 01. 介绍FortiClient和FortiClient EMS ❀ FortiClient EMS ❀ Fortinet 网络安全专家 NSE 5
  12. MyHandler.h对消息accu的处理
  13. B端产品运营:学习笔记
  14. linux 下执行shutdown.sh命令不能关闭tomcat进程的解决方法
  15. 我学编程全靠B站了,真香(第一期)
  16. ubuntu 为可执行程序创建启动图标
  17. oracle中创建事件的作用,Oracle常见等待事件说明(二)-direct path read/write
  18. USACO Section 1.2PROB Miking Cows
  19. Google App Engine+GAppProxy 架设个人代理服务器
  20. 鸿蒙见面会为什么没选在深圳,全军出击!华为智选发布16款新品:鸿蒙分布式技术来了近日,华...

热门文章

  1. 简单工厂模式代码示例
  2. 土木专业学python有什么用-python在土木
  3. Ubuntu-Touch-03:使用SSH连接手机
  4. 如何查找STM32开发资料
  5. XBanner实现3D画廊效果
  6. 【源码】基于MATLAB仿真的移动机器人导航
  7. 如何防护 DNS 放大攻击?
  8. 关于IDEActrl + alt + 下箭头失效的问题
  9. 【Twitter API开发者账户协议必知】
  10. parallels安装linux命令行,Parallels desktop怎么安装linux系统