Shiro笔记(四)Shiro的realm认证
认证流程:
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对象.
后台数据验证流程分析
把AuthenticationToken转换为UsernamePasswordToken.因为我们在之前传入Token对象的时候就是一个这个对象,所以可以强转;
通过用户名把数据从数据库取出来
因为配置了Jedis缓存,所以先从缓存中取,取不到再去数据库中取,在数据库中取出后在放到缓存中
UsernamePasswordToken authenToken = (com.yl.video.security.UsernamePasswordToken) token;从UsernamePasswordToken中取出username;
String userName = token.getUsername();调用数据库的方法,从数据库中查询出对应的用户记录,返回一个数据库中的user对象.
SysUser user = UserUtils.getByLoginName(userName);若登录失败,抛出AuthenticationException等异常.此处只抛出一个账户锁定异常.
if (user != null) { if (Global.BOOLFALSE.equals(user.getLocked())){
throw new AuthenticationException("该已帐号禁止登录.");
}
}
根据用户情况,构建AuthenticationInfo对象并返回.
AuthenticationInfo对象是一个接口对象,常用SimpleAuthenticationInfo对象来实现.
创建一个返回的info对象:
return new SimpleAuthenticationInfo(new Principal(user, authenToken.isMobileLogin()), String.valueOf(user.getPassword()), ByteSource.Util.bytes(userName+user.getSalt()), getName());
三个参数的解释:
- principal:认证的实体信息,可以是传过来的user对象,也可以是username等;
- credentials:数据库中的密码;
- realmName:当前Realm对象的name,调用父类的getName()方法即可.
注意:需要对shiro进行登出操作,否则会有登录成功后再登录错误的对象会造成仍然能登录的情况
密码比对分析
通过AuthenticatingRealm 的credentialsMatcher 属性来进行密码比对 !
- 把密码字符串加密成MD5;
- 替换当前Realm的credentialsMatcher属性,直接使用HashedCredentialsMatcher对象,并设置加密算法即可.
如何替换:
在对密码加密分析的时候,要对两个密码进行分析,一个是从前台获取到的密码,另一个是在数据库中获取到的密码,分别对两个密码进行盐值加密:
对从前台传过来的token对象: 通过在配置文件中配置加密算法即可自动将密码加密成想要的结果:
从数据库中传过来的对象: 因为在shiro的加密中,最后对数据加密是调用了
new SimpleHash(hashAlogorithnName,credentials,salt,hashIterations)方法,所以对数据库中的密码直接进行调用此方法即可. 参数分别为(加密方式,加密的密码,盐值,加密次数).
如何使用盐值加密
- 为什么要对密码进行加盐:
在realm进行密码比对的过程中,当密码相同的时候,用户名无须正确只要密码比对成功即可登录成功,所以要让密码唯一,所以可以对密码加盐,其中盐值必须是唯一的. - 如何对密码进行盐值加密:
- 在doGetAuthenticationInfo方法返回值创建SimpleAuthenticationInfo对象的时候,需使用SimpleAuthenticationInfo(principal,credentials,credentialsSalt,realmName)构造器.
- 使用ByteSource.Util.bytes()来计算盐值.
- 盐值要唯一:一般使用随机字符串或id
- 使用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认证的更多相关文章
- Shiro学习笔记四(Shiro集成WEB)
这两天由于家里出了点事情,没有准时的进行学习.今天补上之前的笔记 -----没有学不会的技术,只有不停找借口的人 学习到的知识点: 1.Shiro 集成WEB 2.基于角色的权限控制 3.基于权限的控 ...
- Shiro笔记(一)Shiro整体介绍
介绍:是一个java的安全(权限)框架 可以完成的功能:认证登录(Authentication).授权(Authorization).加密(cryptography).会话管理(session man ...
- Shiro入门学习之自定义Realm实现认证(四)
一.概述 Shirom默认使用自带的IniRealm,IniRealm从ini配置文件中读取用户的信息,而大部分情况下需要从系统数据库中读取用户信息,所以需要实现自定义Realm,Realm接口如下: ...
- Shiro第四篇【Shiro与Spring整合、快速入门、Shiro过滤器、登陆认证】
Spring与Shiro整合 导入jar包 shiro-web的jar. shiro-spring的jar shiro-code的jar 快速入门 shiro也通过filter进行拦截.filter拦 ...
- Shiro笔记(四)编码/加密
Shiro笔记(四)编码/加密 一.编码和解码 //base64编码.解码 @Test public void testBase64(){ String str="tang"; b ...
- SpringBoot 整合 Shiro 密码登录与邮件验证码登录(多 Realm 认证)
导入依赖(pom.xml) <!--整合Shiro安全框架--> <dependency> <groupId>org.apache.shiro</group ...
- Shiro源码分析-初始化-Realm
在上一篇介绍SecurityManager的初始化过程中,也有realm的粗略介绍. realm的概念在安全领域随处可见: 各种中间件的realm.spring security的realm.shir ...
- Shiro入门之一 -------- Shiro权限认证与授权
一 将Shirojar包导入web项目 二 在web.xml中配置shiro代理过滤器 注意: 该过滤器需要配置在struts2过滤器之前 <!-- 配置Shiro的代理过滤器 --> ...
- Shiro笔记(二)身份验证
Shiro笔记(二)身份验证 一.核心代码 @Test public void helloWorldTest(){ IniSecurityManagerFactory factory = new In ...
随机推荐
- 做了5年的Android,我转Java后台了!
很多人做Java开发4,5年后,都会感觉自己遇到瓶颈.什么都会又什么都不会,如何改变困境,为什么很多人写了7,8年还是一个码农,工作中太多被动是因为不懂底层原理.公司的工作节奏又比较快,难有机会学习架 ...
- Android&Java面试题大全—金九银十面试必备
声明本文由作者:Man不经心授权转载,转载请联系原文作者原文链接:https://www.jianshu.com/p/375ad14096b3, 类加载过程 Java 中类加载分为 3 个步骤:加载. ...
- Glide高级详解—缓存与解码复用
Glide 使用简明的流式语法API,大多数情况下,可能完成图片的设置你只需要:Glide.with(activity) .load(url) .into(imageView); 默认情况下,Glid ...
- 机器学习之SVD分解
一.SVD奇异值分解的定义 假设是一个的矩阵,如果存在一个分解: 其中为的酉矩阵,为的半正定对角矩阵,为的共轭转置矩阵,且为的酉矩阵.这样的分解称为的奇异值分解,对角线上的元素称为奇异值,称为左奇异矩 ...
- iOS项目国际化详解
现在的开发中难免会遇到项目国际化处理,下面把我理解到的国际化相关的知识点进行总结归纳 1 首先是对项目名称,系统性的文字进行名字化,比如程序名字 1,先给项目添加语言 2 添加InfoPlist.st ...
- 进程与程序 并行 并发 串行 阻塞 join函数
进程是正在运行的程序,程序是程序员编写的一对代码,也就是一堆字符,当这堆代码被系统加载到内存并执行,就有了进程. (需要注意的是:一个程序是可以产生多个程序,就像我们可以同时运行多个QQ程序一样,会形 ...
- 五.Bash Shell编程基础入门实战
知识回顾 运行脚本我们一般用sh 不用单独去加执行权限 OLDBOY=10只适用当前环境 局部变量 export OLDBOY把它设置为临时的环境变量应为已经=10了所以不用export OLDBOY ...
- 页面初始化的js函数要放在最最最最最最最前边!否则没效果
简单说一下这个情况,html的页面的各部分都是动态渲染的,所以头部的某些个样式调用函数需要在页面初始化的时候被加载,这个我也是知道的,结果后边代码敲着敲着,就把这个事儿给忘了,然后启动项目的时候,页面 ...
- CF1019C
好玄学的东西... 核心思想:for循环! 首先,我们从前向后扫所有的点,如果这个点没被标记成不可用就把这个点标记成已使用,然后把所有与这个点直接相连的点标记成不可用 接下来,我们从后向前扫所有的点, ...
- txt文档去重复内容
@echo off for /f "delims=" %%i in ('type "%1"') do (if not defined %%i set %%i=A ...