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 ...
随机推荐
- Java基础——GUI编程(三)
接着前两篇学习笔记,这篇主要介绍布局管理器和对话框两部分内容. 一.布局管理器 先拿一个小例子来引出话题,就按照我们随意的添加两个按钮来说,会产生什么样的效果,看执行结果. import java.a ...
- 最小公倍数(BNUOJ30195)
最小公倍数 Time Limit: 0 ms Case Time Limit: 0 ms Memory Limit: 0 KBSubmit: 17 Accepted: 1 This problem w ...
- Android - fragment Manager
fragment基本使用: http://www.cnblogs.com/qlky/p/5415679.html Fragmeng优点 Fragment可以使你能够将activity分离成多个可重用的 ...
- HDU2255(KB10-K 二分图最大权匹配)
奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Subm ...
- Code Signal_练习题_alphabeticShift
Given a string, replace each its character by the next one in the English alphabet (z would be repla ...
- vue2.0父子组件通信的方法
vue2.0组件通信方法:props传值和emit监听.(.sync方法已经移除.详情请点击)(dispatch-和-broadcast方法也已经废弃) props方法传值:Props 现在只能单项传 ...
- Ubuntu下自定义调整CPU工作频率(用于省电或提高性能都好用)
昨天高铁上拿T480切win10系统看电影,为了节电给细调了个省电策略(设置CPU性能30%),不知是不是因为这个原因,今天切回Ubuntu1604工作导致CPU工作频率非常低. 查阅了一下相关方法, ...
- jQuery复选框全选和全选取消
jQuery(".salaryIds").each(function(){ if(jQuery("#salaryIds").attr("checked ...
- Nginx的介绍
1.什么是NGINX: Nginx是一个开源的,支持高性能的.支持高并发的web服务软件和代理服务软件,它是由俄罗斯人lgor Sysoev开发的 Nginx具有高并发(特别是对于静态资源)占用系统资 ...
- 在Android Native层中创建Java虚拟机实例
前言 Android应用中JNI代码,是作为本地方法运行的.而大部分情况下,这些JNI方法均需要传递Dalvik虚拟机实例作为第一个参数.例如,你需要用虚拟机实例来创建jstring和其他的Java对 ...