shiro实战系列(七)之Realm
Realm 是一个能够访问应用程序特定的安全数据(如用户、角色及权限)的组件。Realm 将应用程序特定的数据转 换成一种 Shiro 能够理解的格式,这样 Shiro 能够提供一个单一的易理解的 Subject 编程 API,无论有多少数据源存在 或你应用程序特定的数据是怎样的。 Realm 通常和数据源是一对一的对应关系,如关系数据库,LDAP 目录,文件系统,或其他类似资源。因此,Realm 接口的实现使用数据源特定的 API 来展示授权数据(角色,权限等),如 JDBC,文件 IO,Hibernate 或 JPA,或其他 数据访问 API。
Realm 实质上就是一个特定安全的 DAO 因为这些数据源大多通常存储身份验证数据(如密码的凭证)以及授权数据(如角色或权限),每个 Shiro Realm 能够执行身份验证和授权操作。
(1)Realm configuration
如果使用 Shiro 的 INI 配置文件,你能够自定义及引用 Realm,就像在[main]项中的任何其他对象一样,但它们在 securityManager 中采用两种方法之一进行配置:显式或隐式。
(2)Explicit Assignment
基于迄今的 INI 配置知识,这是一个显示的配置方法。在定义一个或多个 Realm 后,你将它们作为 securityManager 对象的集合属性
显式分配是确定的——你控制具体使用哪一个 Realm 及它们用于身份验证和授权的顺序。Realm 顺序的作用在 Authentication 章的 Authentication Sequence 节进行了详细的介绍。
(3) Implicit Assignment
Not Preferred(不推荐)
这种方法可能引发意想不到的行为,如果你改变 realm 定义的顺序的话。建议你避免使用此方法,并使用显式分配, 它拥有确定的行为。该功能很可能在未来的 Shiro 版本中被废弃或移除。 如果出于某些原因你不想显式地配置 securityManager.realms 的属性,你可以允许 Shiro 检测所有配置好的 realm 并直接将它们指派给 securityManager。 使用这种方法,realm 将会按照它们预先定义好的顺序来指派给 securityManager 实例。 也就是说,对于下面的 shiro.ini 示例:
blahRealm = com.company.blah.Realm
fooRealm = com.company.foo.Realm
barRealm = com.company.another.Realm
# no securityManager.realms assignment here
基本上和下面这一行具有相同的效果:
securityManager.realms = $blahRealm, $fooRealm, $barRealm
然而,实现隐式分配,只是 realm 定义的顺序直接影响到了它们在身份验证和授权尝试中的访问顺序。如果你改变 它们定义的顺序,你将改变主要的 Authenticaor 的 Authentication Sequence 是如何起作用的。 由于这个原因,以及保证明确的行为,我们推荐使用显式分配而不是隐式分配。
(3) Realm Authentication
当你理解了 Shiro 的主要 Authentication 工作流后,了解在一个授权尝试中当 Authenticator 与 Realm 交互时到底发 生了什么是很重要的。
a.Supporting AuthenticationTokens
在 authentication sequence 中已经提到,当在 Realm 被访问来执行一个授权尝试之前,它的supports 方法被调用。 如果返回值为 true,则只有这样它的 getAuthenticationInfo(token)方法才会被调用。 通常 realm 会检查提交的 token 的类型(接口或类)来判断它是否能够处理它。
例如,一个能够处理生物数据的 realm 可能就一点也不理解 UsernamePasswordTokens,这样它将从 supports 方法返回 false。
b.Handling supported AuthenticationTokens
若 Realm 支持一个提交的 AuthenticationToken,那么 Authenticator 将会调用该 Realm 的 getAuthenticationInfo(token) 方法。这有效地代表了一个与 Realm 的后备数据源的授权尝试。该方法按以下方法进行:
1. 为主要的识别信息(帐户识别信息)检查 token。
2. 基于 principal 在数据源中寻找相吻合的帐户数据。
3. 确保 token 支持的 credentials 匹配那些存储在数据源的。
4. 若 credentials 匹配,返回一个封装了 Shiro 能够理解的帐户数据格式的 AuthenticationInfo 实例。
5. 若 credentials 不匹配,则抛出 AuthenticationException 异常。
这是对所有 Realm getAuthenticationInfo 实现的最高级别的工作流。在此方法中,Realm 可以自由地做任何它们想做 的,如记录在审计日志的尝试,更新数据记录,或任何其他可以对该数据存储的身份验证尝试有意义的东西。 唯一需要的东西就是,如果 credentials 匹配给予的 principal(s),那么返回一个非空的 AuthenticationInfo 实例来代表 来自于该数据源的 Subject 帐户信息。
c.Save Time
直接实现 Realm 接口可能导致时间消耗及错误。大多数人们选择 AuthorizingRealm 抽象类的子类而不是从头开始。 这个类实现了常用的 authentication 及 authorization 工作流来节省你的时间和精力。
d.Credentials Matching
在上面的 realmauthentication 工作流中,Realm 不得不验证 Subject 提交的 credentials(如,,密码)必须匹配存储 在数据存储中的 credentials。如果匹配,则被认为身份验证成功,同时系统还必须验证终端用户的身份。 Realm Credentials Matching 这是每个 Realm 的责任,去匹配提交的 credentials 和那些存储在 Realm 后备数据存储中的 credentials,而不是 Authenticator 的责任。每个 Realm 拥有有关私人信息的 credentials 格式,存储及能够执行详细的 credentials 匹配, 然而 Authenticator 只是一个普通的工作量组件。
credentials 的匹配过程在所有应用程序中几乎一样,通常不一样的是进行比较的数据。为了确保该过程是可插入及 可定制的如果需要的话,AuthenticatingRealm 及它的子类支持 CredentialsMatcher 来执行 credentials 对比的概念。 在发现帐户数据后,它以及提交的 AuthenticationToken 用来代表一个 CredentialsMatcher 来判断所提交的是否匹配 所存储的。 Shiro 拥有某些可以让你立即使用的 CredentialsMatcher 实现,如 SimpleCredenticalsMatcher 和 HashedCredentialsMatcher,但如果你想为自定义的逻辑配置一个自定义的实现,你可以像下面一样直接做:
e.Simple Equality Check
所有 Shiro 立即可用的 Realm 的实现默认使用 SimpleCredentialsMatcher。SimpleCredentialsMatcher 执行一个普通的 直接平等检查,关于存储的帐户 credentials 与在 AuthenticationToken 所提交的之间的检查。
例如,若一个 UsernamePasswordToken 被提交后,则 SimpleCredentialsMatcher 验证该密码实际上是否与存储在数 据库中的密码相同。 SimpleCredentialsMatcher 不仅仅为字符串执行直接相等比较。它能够处理大多数常用的字节码,像字符串,字符数 组,字节数组,文件及输入流。请参考它的 JavaDoc 获取更多。
f.Hashing Credentials
并非是存储credentials 在其原始的 form 及执行原始/普通的比较,一个更安全的方式存储终端用户的credentials(如, 密码)是在存储它们到数据存储之前将它们单向散列化。 这确保终端用户的 credentials 绝不会以原始的 form 存储,而且没人会知道原始值。这是一个比纯文本或原始比较 更为安全的机制,同时所有关注安全的应用程序应该较非哈希化的存储更为喜欢。 为了支持这些首选的加密哈希策略,Shiro 提供了 HashedCredentialsMatcher 的实现配置在 realm 上而不是上述 SimpleCredentialsMatcher。 哈希 credentials 及 salting 和多个哈希迭代的好处超出了该 Realm 文档的范围,但绝对要阅读 HashedCredentialsMatcher 的 JavaDoc,其中将详细介绍这些细节。
g.Hashing and Corresponding Matchers
那么,你如何很容易地配置一个启用 Shiro 的应用程序呢? Shiro 提供了多个 HashedCredentialsMatcher 子类实现。你必须在你的 realm 中配置指定的实现来匹配你 hash 化你用 户 credentials 时使用的哈希算法。
例如,假设你的应用程序为身份验证使用用户名/密码对。由于上文所述的哈希凭据的好处,假设当你创建一个用 户帐户时,你想使用 SHA-256 算法单向散列用户的密码。你将哈希用户输入的纯文本密码并保持该值:
既然你使用 SHA-256 散列你用户的密码,你需要告诉 Shiro 使用合适的 HashedCredentialsMatcher 以匹配你的哈希参 数选择。在这个例子中,我们创建了一个随机的 salt 并执行 1024 次哈希迭代,为了强大的安全性(请参见 HashedCredentialsMatcher 的 JavaDoc 获取原因)。这里是完成这项工作的 Shiro INI 配置:
h.SaltedAuthenticationInfo
为了确保这一工程,最后要做的事情是,你的 Realm 实现必须返回一个 SaltedAuthenticationInfo 实例而不是一个普 通的 AuthenticationInfo 实例。SaltedAuthenticationInfo 接口确保在你创建用户帐户(如,user.setPasswordSalt(Salt); call above)时使用的 salt 能够被 HashedCredentialsMatcher 引用. HashedCredentialsMatcher 需要该 salt 为了能够在提交的 AuthenticationToken 上执行相同的哈希技术来判断该 token 是否匹配你保存在数据存储中的东西。因此,如果你为用户密码使用 salting(而且你应该这样做!!!),确保你 的 Realm 实现能够通过返回的 SaltedAuthenticationInfo 实例代表密码。
i.Disabling Authentication
如果出于某些原因,你不想用 Realm 对数据源执行身份验证(也许是由于你只想 Realm 执行授权),你可以彻底地 禁用 Realm 对身份验证的支持通过从 Realm 的 support 方法返回 false。然后你的 realm 在身份验证尝试中永远不会 被访问到。 当然,至少需要一个能够支持 AuthenticationTokens 且已配置的 Realm,如果你想验证 Subjects
shiro实战系列(七)之Realm的更多相关文章
- shiro实战系列(二)之入门实战续
下面讲解基于实战系列一,所以相关的java文件获取pom.xml及其log4j文件同样适用于本次讲解. 一.Using Shiro Using Shiro 现在我们的 SecurityManager ...
- shiro实战系列(一)之入门实战
一.什么是shiro? Apache Shiro 是一个强大而灵活的开源安全框架,它干净利落地处理身份认证,授权,企业会话管理和加密. Apache Shiro 的首要目标是易于使用和理解.安全有 ...
- MP实战系列(七)之集成springboot
springboot是现在比较流行的微服使用的框架,springboot本质上就是将spring+springmvc+mybatis零配置化,基本上springboot的默认配置符合我们的开发.当然有 ...
- shiro实战系列(五)之Authentication(身份验证)
建议学习shiro读读官方文档,虽然不一定读的懂,但是建议要大致浏览,心中有个大概,这样对于学习还是有一定帮助 官网地址:https://shiro.apache.org/ Authenticatio ...
- ElasticSearch实战系列七: Logstash实战使用-图文讲解
前言 在上一篇中我们介绍了Logstash快速入门,本文主要介绍的是ELK日志系统中的Logstash的实战使用.实战使用我打算从以下的几个场景来进行讲解. 时区问题解决方案 在我们使用logstas ...
- shiro实战系列(四)之配置
Shiro之配置 Shiro 被设计成能够在任何环境下工作,从最简单的命令行应用程序到最大的的企业群集应用.由于环境的多样性,使得许多配置机制适用于它的配置. 一. 许多配置选项 Shiro的Secu ...
- shiro实战系列(三)之架构
Apache Shiro 的设计目标是通过直观和易于使用来简化应用程序安全.Shiro 的核心设计体现了大多数人们是如何考虑应用程序安全的——在某些人(或某些事)与应用程序交互的背景下. 应用软件 ...
- shiro实战系列(十三)之单元测试
由于我们已经涉及到了 Subject reference,我们知道 Subject 是“当前执行”用户的特定安全视图,且该 Subject 实 例绑定到一个线程来确保我们知道在线程执行期间的任何时间是 ...
- shiro实战系列(十四)之配置
Shiro 被设计成能够在任何环境下工作,从最简单的命令行应用程序到最大的的企业群集应用.由于环境的多样性,使得许多配置机制适用于它的配置. 一. 许多配置选项 Shiro的SecurityManag ...
随机推荐
- 【C#数据结构系列】栈和队列
一:栈 栈和队列也是线性结构,线性表.栈和队列这三种数据结构的数据元素以及数据元素间的逻辑关系完全相同,差别是线性表的操作不受限制,而栈和队列的操作受到限制.栈的操作只能在表的一端进行,队列的插入操作 ...
- cakephp搭建配置完成后怎么关闭cake标识
在新搭建好cakephp矿建时,准备开发的时候我们会发现页面上有cakephp的标识,影响美观,和开发任务.那么怎么去掉呢? 1.找到FrontDesk\app\View\Layouts\defaul ...
- JS 回调函数、立即执行、for块作用域、try/catch、let、垃圾收集 p3
限于时间关系,加上有些倦意,简单的记录下一些要点: 1.回调函数:就你把函数当成参数传给另一个函数,这个函数在某个时间段会执行这个函数.
- React-Native-Android-Studio整合开发+环境配置+官方实例
linux下React Native开发环境搭建,使用Android-studio工具进行React Native整合开发. 参考React Native的官方文档,通过图文详细记录开发过程.可以查看 ...
- Nginx的性能优化
1.优化worker进程个数: 在高并发.高访问量的WEB服务场景,需要事先启动更多的nginx进程,以保证快速响应并处理大量并发用户的请求,优化nginx进程个数的配置项就是,在nginx.conf ...
- SQLServer 学习笔记之超详细基础SQL语句 Part 8
Sqlserver 学习笔记 by:授客 QQ:1033553122 -----------------------接Part 7------------------- --触发器str_trigge ...
- 如何解决Your project contains C++ files but it is not using a supported native build system
最近因为项目需要下载Android终端模拟器(Android-Terminal-Emulator)源码进行调试编译,编译过程中出现报错 Error:Execution failed for task ...
- openCV 视频分解及合成
1. 视频分解 import cv2 # ************************** # 分解视频 cap=cv2.VideoCapture('1.mp4')#获取一个视频cap isOpe ...
- LeetCode题解之N-ary Tree Postorder Traversal
1.题目描述 2.问题分析 递归. 3.代码 vector<int> postorder(Node* root) { vector<int> v; postNorder(roo ...
- 移除jboss响应中的中间件信息
JBoss 4.2 Suppressing the X-Powered-By header in JBoss 4.2.x can be done by modifying the web.xml fi ...