认证流程:

1.获取当前Subject.调用SecurityUtils.getSubject();

2.测试当前用户是否已经被认证,即是否已经登录,调用Subject的isAurhenticated();

3.若没有认证,则把用户名和密码封装成UsernamePasswordToken对象.

对于B/S应用程序来说,一般用户名和密码是在前台表单中获得的:

1.创建一个表单页面.

2.把请求提交到SpringMVC的Controller.

3.获取用户名和密码.

4.执行登录:调用Subject.login(AuthenticationToken) 方法.

5.自定义Realm方法,从数据库中获取对应的记录,返回给Shiro.

自定义Realm的实现:

1.继承org.apache.shiro.realm.AuthenticatingRealm类.

2.实现doGetAuthenticationInfo(AuthenticationToken)方法.

为什么要继承它且实现它的doGetAuthenticationInfo方法呢?可以跟进源码查看subject.login(token)是怎样工作的:

subject.login(token)->securityManager.login(this, token)->authenticate(token)->authenticator.authenticate(token)->在org.apache.shiro.authc.AbstractAuthenticator中的doAuthenticate(token)方法->查看执行单个认证操作doSingleRealmAuthentication(realms.iterator().next(), authenticationToken)->realm.getAuthenticationInfo(token)->getCachedAuthenticationInfo(token)->在getAuthenticationInfo方法中定义了doGetAuthenticationInfo(token),所以需要实现doGetAuthenticationInfo方法.

6.由shiro完成对密码的比对.

数据传输流程解析:

在执行subject.login(token)方法后,token对象将会传到第5步中自定义Realm中的实现的doGetAuthenticationInfo方法中的AuthenticationToken对象中,这样就可以将token对象传到Realm域中了,我们可以对token进行比对判断登录是否成功.

流程:

前台form表单提交数据->Controller->subject.login(token)->shiro域中接收到token对象.

后台数据验证流程分析

  1. 把AuthenticationToken转换为UsernamePasswordToken.因为我们在之前传入Token对象的时候就是一个这个对象,所以可以强转;

    通过用户名把数据从数据库取出来

    因为配置了Jedis缓存,所以先从缓存中取,取不到再去数据库中取,在数据库中取出后在放到缓存中

    UsernamePasswordToken authenToken = (com.yl.video.security.UsernamePasswordToken) token;

  2. 从UsernamePasswordToken中取出username;

    String userName = token.getUsername();

  3. 调用数据库的方法,从数据库中查询出对应的用户记录,返回一个数据库中的user对象.

    SysUser user = UserUtils.getByLoginName(userName);

  4. 若登录失败,抛出AuthenticationException等异常.此处只抛出一个账户锁定异常.

     if (user != null) {
    
     if (Global.BOOLFALSE.equals(user.getLocked())){
    throw new AuthenticationException("该已帐号禁止登录.");
    }
    }
  5. 根据用户情况,构建AuthenticationInfo对象并返回.

AuthenticationInfo对象是一个接口对象,常用SimpleAuthenticationInfo对象来实现.

创建一个返回的info对象:

return new SimpleAuthenticationInfo(new Principal(user, authenToken.isMobileLogin()), String.valueOf(user.getPassword()), ByteSource.Util.bytes(userName+user.getSalt()), getName());

三个参数的解释:

  1. principal:认证的实体信息,可以是传过来的user对象,也可以是username等;
  2. credentials:数据库中的密码;
  3. realmName:当前Realm对象的name,调用父类的getName()方法即可.

注意:需要对shiro进行登出操作,否则会有登录成功后再登录错误的对象会造成仍然能登录的情况

密码比对分析

通过AuthenticatingRealm 的credentialsMatcher 属性来进行密码比对 !

  1. 把密码字符串加密成MD5;
  2. 替换当前Realm的credentialsMatcher属性,直接使用HashedCredentialsMatcher对象,并设置加密算法即可.

如何替换:

在对密码加密分析的时候,要对两个密码进行分析,一个是从前台获取到的密码,另一个是在数据库中获取到的密码,分别对两个密码进行盐值加密:

  1. 对从前台传过来的token对象: 通过在配置文件中配置加密算法即可自动将密码加密成想要的结果:





  2. 从数据库中传过来的对象: 因为在shiro的加密中,最后对数据加密是调用了new SimpleHash(hashAlogorithnName,credentials,salt,hashIterations)方法,所以对数据库中的密码直接进行调用此方法即可. 参数分别为(加密方式,加密的密码,盐值,加密次数).

如何使用盐值加密

  1. 为什么要对密码进行加盐:

    在realm进行密码比对的过程中,当密码相同的时候,用户名无须正确只要密码比对成功即可登录成功,所以要让密码唯一,所以可以对密码加盐,其中盐值必须是唯一的.
  2. 如何对密码进行盐值加密:
    1. 在doGetAuthenticationInfo方法返回值创建SimpleAuthenticationInfo对象的时候,需使用SimpleAuthenticationInfo(principal,credentials,credentialsSalt,realmName)构造器.
    2. 使用ByteSource.Util.bytes()来计算盐值.
    3. 盐值要唯一:一般使用随机字符串或id
    4. 使用new SimpleHash(hashAlogorithnName,credentials,salt,hashIterations)来计算盐值加密后的值.

多realm认证

多realm认证原理:

多realm认证是通过ModularRealmAuthenticator对象进行认证的,我们可以在spring-shiro中配置多个realm,并将多个bean统一交给ModularRealmAuthenticator进行管理,然后在SecurityManager中配置ModularRealmAuthenticator来进行实现多realm认证的效果。

多realm的认证配置:





在多realm配置的时候一般将两个或多个realms放在securityManager中而不是放在authenticator中,如下图:

这样的好处是当授权的时候比较方便。

多realm的认证策略

Shiro笔记(四)Shiro的realm认证的更多相关文章

  1. Shiro学习笔记四(Shiro集成WEB)

    这两天由于家里出了点事情,没有准时的进行学习.今天补上之前的笔记 -----没有学不会的技术,只有不停找借口的人 学习到的知识点: 1.Shiro 集成WEB 2.基于角色的权限控制 3.基于权限的控 ...

  2. Shiro笔记(一)Shiro整体介绍

    介绍:是一个java的安全(权限)框架 可以完成的功能:认证登录(Authentication).授权(Authorization).加密(cryptography).会话管理(session man ...

  3. Shiro入门学习之自定义Realm实现认证(四)

    一.概述 Shirom默认使用自带的IniRealm,IniRealm从ini配置文件中读取用户的信息,而大部分情况下需要从系统数据库中读取用户信息,所以需要实现自定义Realm,Realm接口如下: ...

  4. Shiro第四篇【Shiro与Spring整合、快速入门、Shiro过滤器、登陆认证】

    Spring与Shiro整合 导入jar包 shiro-web的jar. shiro-spring的jar shiro-code的jar 快速入门 shiro也通过filter进行拦截.filter拦 ...

  5. Shiro笔记(四)编码/加密

    Shiro笔记(四)编码/加密 一.编码和解码 //base64编码.解码 @Test public void testBase64(){ String str="tang"; b ...

  6. SpringBoot 整合 Shiro 密码登录与邮件验证码登录(多 Realm 认证)

    导入依赖(pom.xml)  <!--整合Shiro安全框架--> <dependency> <groupId>org.apache.shiro</group ...

  7. Shiro源码分析-初始化-Realm

    在上一篇介绍SecurityManager的初始化过程中,也有realm的粗略介绍. realm的概念在安全领域随处可见: 各种中间件的realm.spring security的realm.shir ...

  8. Shiro入门之一 -------- Shiro权限认证与授权

    一  将Shirojar包导入web项目 二 在web.xml中配置shiro代理过滤器 注意: 该过滤器需要配置在struts2过滤器之前 <!-- 配置Shiro的代理过滤器 -->  ...

  9. Shiro笔记(二)身份验证

    Shiro笔记(二)身份验证 一.核心代码 @Test public void helloWorldTest(){ IniSecurityManagerFactory factory = new In ...

随机推荐

  1. Android中播放音乐的几种方式

    前言 前几天一直在研究RxJava2,也写了记录了几篇博客,但因为工作任务原因,需要研究音频相关的知识,暂时放下Rxjava,本文的demo中,MediaPalyer 部分使用RxJava编写一点逻辑 ...

  2. 【转】光盘和U盘安装win7和ubuntu14.04全步骤

    详细步骤见原链接:http://brianway.github.io/2016/01/18/linux-win7-ubuntu-setup-by-USBandCD/ 安装Linux步骤 1. 在win ...

  3. 判断ie浏览器7、8、9三个版本

    判断ie浏览器7.8.9三个版本   上午的时候,本来是想做一个position:fixed在各个浏览器下兼容的方案的,但是发现ie7/8下面的position:fixed只支持一个屏幕,如果内容高度 ...

  4. LeetCode(114): 二叉树展开为链表

    Medium! 题目描述: 给定一个二叉树,原地将它展开为链表. 例如,给定二叉树 1 / \ 2 5 / \ \ 3 4 6 将其展开为: 1 \ 2 \ 3 \ 4 \ 5 \ 6 解题思路: 这 ...

  5. LeetCode(94):二叉树的中序遍历

    Medium! 题目描述: 给定一个二叉树,返回它的中序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,3,2] 进阶: 递归算法很简单,你可以通过迭代算法完成吗 ...

  6. 【es】创建索引和映射

    参考:http://www.cnblogs.com/sheeva/p/4837881.html 创建索引: curl -XPUT 'http://localhost:9200/some_index' ...

  7. 【python】控制台输出颜色

    来源:http://www.cnblogs.com/yinjia/p/5559702.html 在开发项目过程中,为了方便调试代码,经常会向stdout中输出一些日志,默认的这些日志就直接显示在了终端 ...

  8. DOBRI

    问题 : DOBRI 时间限制: 1 Sec  内存限制: 128 MB 题目描述 给出一个包含N个整数的序列A,定义这个序列A的前缀和数组为SUM数组 ,当SUM数组中的第i个元素等于在i前面的三个 ...

  9. python+selenium十五:CSS与Jquery

    在css中,id用#表示,class用.表示,要定位标签直接写标签名,其他属性就用[xxx='xxx'] 一.css定位 1.属性定位:可以通过任意属性定位,不局限于id.class.name.tag ...

  10. 论文阅读笔记七:Structure Inference Network:Object Detection Using Scene-Level Context and Instance-Level Relationships(CVPR2018)

    结构推理网络:基于场景级与实例级目标检测 原文链接:https://arxiv.org/abs/1807.00119 代码链接:https://github.com/choasup/SIN Yong ...