第五章:Realm
一,UserRealm
1,UserRealm父类AuthorizingRealm将获取Subject相关信息分成两步:
1.1,获取身份验证信息(doGetAuthenticationInfo):
首先根据传入的用户名获取User信息;然后如果user为空,那么抛出没找到帐号异常UnknownAccountException;如果user找到但锁定了抛出锁定异常LockedAccountException;最后生成AuthenticationInfo信息,交给间接父类AuthenticatingRealm使用CredentialsMatcher进行判断密码是否匹配,如果不匹配将抛出密码错误异常IncorrectCredentialsException;在组装SimpleAuthenticationInfo信息时,需要传入:身份信息(用户名)、凭据(密文密码)、盐(username+salt),CredentialsMatcher使用盐加密传入的明文密码和此处的密文密码进行匹配。
1.2,授权信息(doGetAuthorizationInfo);
PrincipalCollection是一个身份集合,因为我们现在就一个Realm,所以直接调用getPrimaryPrincipal得到之前传入的用户名即可;然后根据用户名调用UserService接口获取角色及权限信息。
二,AuthenticationToken
1,AuthenticationToken用于收集用户提交的身份(如用户名)及凭据(如密码):
public interface AuthenticationToken extends Serializable {
Object getPrincipal(); //身份
Object getCredentials(); //凭据
}

扩展接口RememberMeAuthenticationToken:提供了“boolean isRememberMe()”现“记住我”的功能;
扩展接口是HostAuthenticationToken:提供了“String getHost()”方法用于获取用户“主机”的功能。
Shiro提供了一个直接拿来用的UsernamePasswordToken,用于实现用户名/密码Token组,另外其实现了RememberMeAuthenticationToken和HostAuthenticationToken,可以实现记住我及主机验证的支持。
三,AuthenticationInfo
AuthenticationInfo有两个作用:
1、如果Realm是AuthenticatingRealm子类,则提供给AuthenticatingRealm内部使用的CredentialsMatcher进行凭据验证;(如果没有继承它需要在自己的Realm中自己实现验证);
2、提供给SecurityManager来创建Subject(提供身份信息);

一般返回SimpleAuthenticationInfo即可。
四,AuthorizationInfo
AuthorizationInfo用于聚合授权信息的:
public interface AuthorizationInfo extends Serializable {
Collection<String> getRoles(); //获取角色字符串信息
Collection<String> getStringPermissions(); //获取权限字符串信息
Collection<Permission> getObjectPermissions(); //获取Permission对象信息
}
当我们使用AuthorizingRealm时,如果身份验证成功,在进行授权时就通过doGetAuthorizationInfo方法获取角色/权限信息用于授权验证。

Shiro提供了一个实现SimpleAuthorizationInfo,大多数时候使用这个即可。
五,Subject

Subject是Shiro的核心对象,基本所有身份验证、授权都是通过Subject完成。
1、身份信息获取
Object getPrincipal(); //Primary Principal PrincipalCollection getPrincipals(); // PrincipalCollection
2、身份验证
void login(AuthenticationToken token) throws AuthenticationException;
boolean isAuthenticated();
boolean isRemembered();
通过login登录,如果登录失败将抛出相应的AuthenticationException,如果登录成功调用isAuthenticated就会返回true,即已经通过身份验证;如果isRemembered返回true,表示是通过记住我功能登录的而不是调用login方法登录的。isAuthenticated/isRemembered是互斥的,即如果其中一个返回true,另一个返回false。
3、角色授权验证
boolean hasRole(String roleIdentifier);
boolean[] hasRoles(List<String> roleIdentifiers);
boolean hasAllRoles(Collection<String> roleIdentifiers);
void checkRole(String roleIdentifier) throws AuthorizationException;
void checkRoles(Collection<String> roleIdentifiers) throws AuthorizationException;
void checkRoles(String... roleIdentifiers) throws AuthorizationException;
hasRole*进行角色验证,验证后返回true/false;而checkRole*验证失败时抛出AuthorizationException异常。
4、权限授权验证
boolean isPermitted(String permission);
boolean isPermitted(Permission permission);
boolean[] isPermitted(String... permissions);
boolean[] isPermitted(List<Permission> permissions);
boolean isPermittedAll(String... permissions);
boolean isPermittedAll(Collection<Permission> permissions);
void checkPermission(String permission) throws AuthorizationException;
void checkPermission(Permission permission) throws AuthorizationException;
void checkPermissions(String... permissions) throws AuthorizationException;
void checkPermissions(Collection<Permission> permissions) throws AuthorizationException;
isPermitted*进行权限验证,验证后返回true/false;而checkPermission*验证失败时抛出AuthorizationException。
5、会话
Session getSession(); //相当于getSession(true)
Session getSession(boolean create);
类似于Web中的会话。如果登录成功就相当于建立了会话,接着可以使用getSession获取;如果create=false如果没有会话将返回null,而create=true如果没有会话会强制创建一个。
6、退出
void logout();
7、RunAs
void runAs(PrincipalCollection principals) throws NullPointerException, IllegalStateException;
boolean isRunAs();
PrincipalCollection getPreviousPrincipals();
PrincipalCollection releaseRunAs();
RunAs即实现“允许A假设为B身份进行访问”;通过调用subject.runAs(b)进行访问;接着调用subject.getPrincipals将获取到B的身份;此时调用isRunAs将返回true;而a的身份需要通过subject. getPreviousPrincipals获取;如果不需要RunAs了调用subject. releaseRunAs即可。
8、多线程
<V> V execute(Callable<V> callable) throws ExecutionException;
void execute(Runnable runnable);
<V> Callable<V> associateWith(Callable<V> callable);
Runnable associateWith(Runnable runnable);
实现线程之间的Subject传播,因为Subject是线程绑定的;因此在多线程执行中需要传播到相应的线程才能获取到相应的Subject。最简单的办法就是通过execute(runnable/callable实例)直接调用;或者通过associateWith(runnable/callable实例)得到一个包装后的实例;它们都是通过:1、把当前线程的Subject绑定过去;2、在线程执行结束后自动释放。
Subject自己不会实现相应的身份验证/授权逻辑,而是通过DelegatingSubject委托给SecurityManager实现;及可以理解为Subject是一个面门。
对于Subject的构建一般没必要我们去创建;一般通过SecurityUtils.getSubject()获取:
public static Subject getSubject() {
Subject subject = ThreadContext.getSubject();
if (subject == null) {
subject = (new Subject.Builder()).buildSubject();
ThreadContext.bind(subject);
}
return subject;
}
即首先查看当前线程是否绑定了Subject,如果没有通过Subject.Builder构建一个然后绑定到现场返回。
第五章:Realm的更多相关文章
- 第六章 Realm及相关对象——《跟我学Shiro》
转发地址:https://www.iteye.com/blog/jinnianshilongnian-2022468 目录贴:跟我学Shiro目录贴 6.1 Realm [2.5 Realm]及[3. ...
- 《Django By Example》第五章 中文 翻译 (个人学习,渣翻)
书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者@ucag注:大家好,我是新来的翻译, ...
- 《Entity Framework 6 Recipes》中文翻译系列 (22) -----第五章 加载实体和导航属性之延迟加载
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 第五章 加载实体和导航属性 实体框架提供了非常棒的建模环境,它允许开发人员可视化地使 ...
- 精通Web Analytics 2.0 (7) 第五章:荣耀之钥:度量成功
精通Web Analytics 2.0 : 用户中心科学与在线统计艺术 第五章:荣耀之钥:度量成功 我们的分析师常常得不到我们应得的喜欢,尊重和资金,因为我们没有充分地衡量一个黄金概念:成果.因为我们 ...
- 《Linux内核设计与实现》读书笔记 第五章 系统调用
第五章系统调用 系统调用是用户进程与内核进行交互的接口.为了保护系统稳定可靠,避免应用程序恣意忘形. 5.1与内核通信 系统调用在用户空间进程和硬件设备间添加了一个中间层, 作用:为用户空间提供了一种 ...
- Java语言程序设计(基础篇) 第五章 循环
第五章 循环 5.2 while循环 1.while循环的语法如下: while(循环继续条件){ //循环体 语句(组); } 2.程序:提示用户为两个个位数相加的问题给出答案 package co ...
- 读《编写可维护的JavaScript》第五章总结
第五章 UI层的松耦合 5.1 什么是松耦合 在Web开发中,用户界面是由三个彼此隔离又相互作用的层定义的: HTML是用来定义页面的数据和语义 CSS用来给页面添加样式 JavaScript用来给页 ...
- 《Linux内核设计与实现》课本第五章学习笔记——20135203齐岳
<Linux内核设计与实现>课本第五章学习笔记 By20135203齐岳 与内核通信 用户空间进程和硬件设备之间通过系统调用来交互,其主要作用有三个. 为用户空间提供了硬件的抽象接口. 保 ...
- Android深度探索--HAL与驱动开发----第五章读书笔记
第五章主要学习了搭建S3C6410开发板的测试环境.首先要了解到S3C6410是一款低功耗.高性价比的RISC处理器它是基于ARMI1内核,广泛应用于移动电话和通用处理等领域. 开发板从技术上说与我们 ...
- 《java编程思想》读书笔记(一)开篇&第五章(1)
2017 ---新篇章 今天终于找到阅读<java编程思想>这本书方法了,表示打开了一个新世界. 第一章:对象导论 内容不多但也有20页,主要是对整本书的一个概括.因为已经有过完整JAV ...
随机推荐
- C#3.0导航
C#3.0主要特性 智能的编译器 编译器,背后的默默付出者 Lamdba表达式与表达式树 匿名方法的革命 扩展方法 优雅的对类进扩展 (待完成) LINQ 还有这种操作? (待完成)
- 2018-7-27银行卡bin大全-根据银行卡开头查银行
支付宝卡号验证工具 https://ccdcapi.alipay.com/validateAndCacheCardInfo.json?_input_charset=utf-8&cardNo=银 ...
- spring cloud 配置zuul实用
在线演示 演示地址:http://139.196.87.48:9002/kitty 用户名:admin 密码:admin 技术背景 前面我们通过Ribbon或Feign实现了微服务之间的调用和负载均衡 ...
- web前端安全
之前对web前端安全进行了总结,想给大家分享一下,有不对的地方,大家多多交流,由于写在了PPT上,只好给大家一张一张粘上来,希望大家不要在意,了解知识为主
- JDK源码分析(10)之 Hashtable 相关
本文的目的并不是让你对Hashtable更加了解,然后灵活运用:因为Hashtable的一个历史遗留的类,目前并不建议使用,所以本文主要和HashMap对比,感受同样功能的不同实现,知道什么是好的代码 ...
- Oracle学习笔记三
一.创建表空间 表空间是ORACLE数据库的逻辑单元.数据库--表空间 一个表空间可以与多个数据文件(物理结构)关联一个数据库下可以建立多个表空间,一个表空间可以建立多个用户个用户下可以建立多个表. ...
- 第3章 支持和规范 - Identity Server 4 中文文档(v1.0.0)
IdentityServer实现以下规范: 3.1 OpenID Connect OpenID Connect Core 1.0 (规范) OpenID Connect Discovery 1.0 ( ...
- js中获取URL参数的共通方法getRequest()方法
getRequest : function() { var url = location.search; //获取url中"?"符后的字串 var theRequest = new ...
- 【SpringBoot】拦截器使用@Autowired注入接口为null解决方法
最近使用SpringBoot的自定义拦截器,在拦截器中注入了一个DAO,准备下面作相应操作,拦截器代码: public class TokenInterceptor implements Handle ...
- SQL Server中几种遍历方式比较
SQL遍历解析 在SQL的存储过程,函数中,经常需要使用遍历(遍历table),其中游标.临时表等遍历方法很常用.面对小数据量,这几种遍历方法均可行,但是面临大数据量时,就需要择优选择,不同的遍历方法 ...