shiro简介,认证,认证流程,自定义realm,散列算法

第一节:shiro简介

1.    重点:认识shiro,认识shiro架构及相关对象。

2.    课程实际内容

a)    简介:简单回顾rbac,引出权限管理框架shiro和spring security。

b)    简介:什么是shiro

c)     简介:为什么要学习shiro

d)    重点:shiro架构并将shiro的组成部分和rabc中关键对象进行对比

e)    简介:如何获取shiro相关资源

3.    重点:课堂总结

a)    总结shiro架构中的关键对象。并记忆。知道认证和授权相关的术语。

第二节:shiro认证

1. 重点:讲解认证流程并实现入门程序。

2. 课程实际内容

a)    重点:shiro认证流程

b)    重点:入门程序实现

c)     简介:测试

3. 重点:课堂总结

a)    认证实现

练习20分钟

 

第三节:分析认证执行流程,及源码分析

1. 重点:认证执行流程及常见异常

2. 课程实际内容

a)    重点:认证执行流程

b)    简介:带领学生看看源码

c)    重点:常见异常讲解及分析

3. 重点:课堂总结

a)    认证执行流程及常见异常

第四节:自定义Realm实现

1. 重点:理解Realm的作用,及实现自定义Realm

2. 课程实际内容

a)    重点:什么是Realm,及其接口

b)    重点:自定义Realm实现

c)    重点:测试

3. 重点:课堂总结

a) 自定义Realm的相关步骤

练习20分钟

第五节:散列算法

1. 重点:shiro中使用散列算法

2. 课程实际内容

a)    简介:散列算法简介

b)  重点:在自定义的Realm中使用md5

c)    重点:配置凭证匹配器

d)    简介:测试

3. 重点:课堂总结

a)shiro中散列算法的使用

 

 

第一节课备课参考

核心脉络

回顾rbac,由rbac引出权限框架的必要性。介绍权限框架shiro与spring security。介绍shiro及其架构。

重点:

1.    Shiro架构及其相关对象

 

难点:

1.  Shiro架构及其相关对象

 

互动:之前讲述了rbac权限管理,并实现了其功能。几乎在所有的系统中都会涉及权限问题,在不同的系统中不断重复几乎相同的代码。显然这些相同的部分可以抽取出来形成一套框架,这就是权限管理框架。权限管理框架目前使用最多的是shiro和spring security.

接下来我们开始学习shiro.

shiro介绍

什么是shiro

Shiro是apache旗下一个开源框架,它将软件系统的安全认证相关的功能抽取出来,实现用户身份认证,权限授权、加密、会话管理等功能,组成了一个通用的安全认证框架

为什么要学shiro

         既然shiro将安全认证相关的功能抽取出来组成一个框架,使用shiro就可以非常快速的完成认证、授权等功能的开发,降低系统成本。

         shiro使用广泛,shiro可以运行在web应用,非web应用,集群分布式应用中越来越多的用户开始使用shiro。

         java领域中spring security(原名Acegi)也是一个开源的权限管理框架,但是spring security依赖spring运行,而shiro就相对独立,最主要是因为shiro使用简单、灵活,所以现在越来越多的用户选择shiro。

 

Shiro架构

 

 

 

Subject

         Subject即主体,外部应用与subject进行交互,subject记录了当前操作用户,将用户的概念理解为当前操作的主体,可能是一个通过浏览器请求的用户,也可能是一个运行的程序。     Subject在shiro中是一个接口,接口中定义了很多认证授相关的方法,外部程序通过subject进行认证授,而subject是通过SecurityManager安全管理器进行认证授权

 

SecurityManager

         SecurityManager即安全管理器,对全部的subject进行安全管理,它是shiro的核心,负责对所有的subject进行安全管理。通过SecurityManager可以完成subject的认证、授权等,实质上SecurityManager是通过Authenticator进行认证,通过Authorizer进行授权,通过SessionManager进行会话管理等。

         SecurityManager是一个接口,继承了Authenticator, Authorizer, SessionManager这三个接口。

 

Authenticator

         Authenticator即认证器,对用户身份进行认证,Authenticator是一个接口,shiro提供ModularRealmAuthenticator实现类,通过ModularRealmAuthenticator基本上可以满足大多数需求,也可以自定义认证器。

Authorizer

         Authorizer即授权器,用户通过认证器认证通过,在访问功能时需要通过授权器判断用户是否有此功能的操作权限。

 

realm

         Realm即领域,相当于datasource数据源,securityManager进行安全认证需要通过Realm获取用户权限数据,比如:如果用户身份数据在数据库那么realm就需要从数据库获取用户身份信息。

         注意:不要把realm理解成只是从数据源取数据,在realm中还有认证授权校验的相关的代码。

 

sessionManager

sessionManager即会话管理,shiro框架定义了一套会话管理,它不依赖web容器的session,所以shiro可以使用在非web应用上,也可以将分布式应用的会话集中在一点管理,此特性可使它实现单点登录。

SessionDAO

SessionDAO会话dao,是对session会话操作的一套接口,比如要将session存储到数据库,可以通过jdbc将会话存储到数据库。

CacheManager

CacheManager即缓存管理,将用户权限数据存储在缓存,这样可以提高性能。

Cryptography

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

 

Shiro资源获取

地址:http://shiro.apache.org/

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

 

 

参考lib目录:

 

第二节课备课参考

核心脉络

在上一节中介绍了shiro的架构及相关组件,那么接下来就开始一个shiro的案例。在本次课中,实现shiro的认证

重点:

1. Shiro的认证流程及代码实现

难点:

1. Shiro的认证流程及代码实现

认证基本概念

身份验证

即在应用中谁能证明他就是他本人。一般提供如他们的身份ID一些标识信息来

表明他就是他本人,如提供身份证,用户名/密码来证明。

在 shiro 中,用户需要提供principals (身份)和credentials(证明)给shiro,从而应用能

验证用户身份:

principals

身份,即主体的标识属性,可以是任何东西,如用户名、邮箱等,唯一即可。

一个主体可以有多个principals,但只有一个Primary principals,一般是用户名/密码/手机号。

credentials

证明/凭证,即只有主体知道的安全值,如密码/数字证书等。

最常见的principalscredentials组合就是用户名/密码了。接下来先进行一个基本的身份认证。

认证流程

入门程序(用户登陆和退出)

a)创建java工程

b)加入相关jar包

commons-beanutils-1.9.2.jar

commons-logging-1.2.jar

junit-4.10.jar

shiro-all-1.2.3.jar

slf4j-api-1.7.7.jar

log4j-1.2.17.jar

slf4j-log4j12-1.7.5.jar

c)log4j.properties日志配置文件

log4j.rootLogger=debug, stdout

log4j.appender.stdout=org.apache.log4j.ConsoleAppender

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m %n

 

d)配置shiro环境文件shiro.ini

通过Shiro.ini配置文件初始化SecurityManager环境。

[users]

zhangsan=1111

lisi=1111

 

e)代码实现

//用户登录和退出

   @Test

   public void testAuthenticator(){

      // 构建SecurityManager工厂,IniSecurityManagerFactory可以从ini文件中初始化SecurityManager环境

      Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");

      //通过工厂获得SecurityManager实例

      SecurityManager securityManager = factory.getInstance();

      //将securityManager设置到运行环境中

      SecurityUtils.setSecurityManager(securityManager);

      //获取subject实例

      Subject subject = SecurityUtils.getSubject();

      //创建用户名,密码身份验证Token

      UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "1111");

      try {

         //登录,即身份验证

         subject.login(token);

      } catch (AuthenticationException e) {

         e.printStackTrace();

         //身份认证失败

      }

      //断言用户已经登录

      Assert.assertEquals(true, subject.isAuthenticated());

      //退出

      subject.logout();

   }

测试

第三节课备课参考

核心脉络

分析认证执行流程,分析源码,进行核心代码解读。讲解常见异常

重点:

1. 认证执行流程

难点:

1. 分析源码

 

互动:接下来,我们一起来看看高大上的东西----源码。通过源码的分析大家可以对shiro的底层原理深层次的搞清楚

认证执行流程

 

1、  创建token令牌,token中有用户提交的认证信息即账号和密码

2、  执行subject.login(token),最终由securityManager通过Authenticator进行认证

3、  Authenticator的实现ModularRealmAuthenticator调用realm从ini配置文件取用户真实的账号和密码,这里使用的是IniRealm(shiro自带)

4、  IniRealm先根据token中的账号去ini中找该账号,如果找不到则给ModularRealmAuthenticator返回null,如果找到则匹配密码,匹配密码成功则认证通过。

 

常见的异常

n  UnknownAccountException

账号不存在异常如下:

org.apache.shiro.authc.UnknownAccountException: No account found for user。。。。

 

 

n  IncorrectCredentialsException

当输入密码错误会抛此异常,如下:

org.apache.shiro.authc.IncorrectCredentialsException: Submitted credentials for token[org.apache.shiro.authc.UsernamePasswordToken - zhangsan, rememberMe=false] didnot match the expected credentials.

 

 

更多如下:

DisabledAccountException(帐号被禁用)

LockedAccountException(帐号被锁定)

ExcessiveAttemptsException(登录失败次数过多)

ExpiredCredentialsException(凭证过期)等

第四节课备课参考

核心脉络

回顾shiro架构图,讲解realm的作用,以及自定义Realm的必要性。

重点:

1. 自定义Realm

难点:

1. 自定义Realm

 

互动:在分析了源码以后,那么接下来看看shiro给我们提供了很多自定义的空间来实现我们自己要想的功能。其中最常用的自定义组件是Realm.

什么是Realm

Realm 是可以访问程序特定的安全数据如用户、角色、权限等的一个组件。Realm会将这些程序特定的安全数据转换成一种shiro可以理解的形式,shiro就可以依次提供容易理解的Subject程序API而不管有多少数据源或者程序中你的数据如何组织。

Realm 通常和数据源如数据库、LDAP目录、文件系统或者其它类似的数据源是一对一的关系,所以,可以用数据源相应的API如JDBC、File IO、 hibernate 或者JPA以及其它的API来实现Realm接口,从而获取授权的相关数据(角色、权限等)。

realm本质上就是一个指定安全的DAO。

自定义Realm

Shiro默认使用自带的IniRealm,IniRealm从ini配置文件中读取用户的信息,大部分情况下需要从系统的数据库中读取用户信息,所以需要自定义realm。

 

Realm接口

最基础的是Realm接口,CachingRealm负责缓存处理,AuthenticationRealm负责认证,AuthorizingRealm负责授权,通常自定义的realm继承AuthorizingRealm。

自定义Realm实现

/**

 * 自定义Realm实现

 * @author邹波

 * @version 1.0

 * @date 2016-1-21

 */

public class UserRealm extends AuthorizingRealm {

   @Override

   public String getName() {

      return "UserRealm";

   }

   //用于认证

   @Override

   protected AuthenticationInfo doGetAuthenticationInfo(

         AuthenticationToken token) throws AuthenticationException {

      //从token中获取身份信息

      String username = (String)token.getPrincipal();

      //根据用户名到数据库中取出用户信息  如果查询不到 返回null

      String password = "1111";//假如从数据库中获取密码为1111

      //返回认证信息

      SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username, password, this.getName());

      return simpleAuthenticationInfo;

   }

   //用于授权

   @Override

   protected AuthorizationInfo doGetAuthorizationInfo(

         PrincipalCollection principals) {

      return null;

   }

}

配置Realm

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

[main]

#自定义 realm

userRealm=cn.siggy.realm.UserRealm

#将realm设置到securityManager

securityManager.realms=$userRealm

 

测试

 

第五节课备课参考

核心脉络

回顾在认证流程中对于密码的处理。阐述密码加密的必要性和重要性。引出散列算法。

重点:

1. Shiro中散列算法的使用

难点:

1.Shiro中散列算法的使用

 

散列算法

散列算法一般用于生成数据的摘要信息,是一种不可逆的算法,一般适合存储密码之类的数据,常见的散列算法如MD5、SHA等。一般进行散列时最好提供一个salt(盐),比如

加密密码“admin”,产生的散列值是“21232f297a57a5a743894a0e4a801fc3”,可以到一

些md5 解密网站很容易的通过散列值得到密码“admin”,即如果直接对密码进行散列相

对来说破解更容易,此时我们可以加一些只有系统知道的干扰数据,如用户名和ID(即盐);

这样散列的对象是“密码+用户名+ID”,这样生成的散列值相对来说更难破解。

MD5算法

/**

 *

 * @author邹波

 * @version 1.0

 * @date 2016-1-21

 */

public class ShiroTest {

   //shiro提供了现成的加密类  Md5Hash

   @Test

   public void testMd5(){

      //MD5加密

      String password = new Md5Hash("1111").toString();

      System.out.println("加密后:"+password);

      //加盐  salt  默认一次散列

      String password_salt=new Md5Hash("1111", "siggy").toString();

      System.out.println("加盐后:"+password_salt);

      //散列2

      String password_salt_2 = new Md5Hash("1111", "siggy", 2).toString();

      System.out.println("散列2次:"+password_salt_2);

      //使用SimpleHash

      SimpleHash hash = new SimpleHash("MD5", "1111", "siggy", 2);

      System.out.println("simpleHash:"+hash.toString());

   }

}

 

在自定义Realm中使用散列

Realm实现代码

public class UserRealm extends AuthorizingRealm {

   @Override

   public String getName() {

      return "UserRealm";

   }

   //用于认证

   @Override

   protected AuthenticationInfo doGetAuthenticationInfo(

         AuthenticationToken token) throws AuthenticationException {

      //从token中获取身份信息

      String username = (String)token.getPrincipal();

      //根据用户名到数据库中取出用户信息  如果查询不到 返回null

      //按照固定规则加密码结果 ,此密码 要在数据库存储,原始密码 是1111,盐是siggy 2次散列

      String password = "1620d20433da92e2523928e351e90f97";//假如从数据库中获取密码为1111

      //返回认证信息  

      SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username,

            password, ByteSource.Util.bytes("siggy"),this.getName());

      return simpleAuthenticationInfo;

   }

   //用于授权

   @Override

   protected AuthorizationInfo doGetAuthorizationInfo(

         PrincipalCollection principals) {

      return null;

   }

}

 

Realm配置

Shiro.ini 在配置文件中,需指定凭证匹配器

[main]

#定义凭证匹配器

credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher

#散列算法

credentialsMatcher.hashAlgorithmName=md5

#散列次数

credentialsMatcher.hashIterations=2

 

#将凭证匹配器设置到realm

userRealm=cn.siggy.realm.UserRealm

userRealm.credentialsMatcher=$credentialsMatcher

securityManager.realms=$userRealm

 

测试

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值