Apache Shiro Realms
Realm 是可以访问程序特定的安全数据如用户、角色、权限等的一个组件。Realm会将这些程序特定的安全数据转换成一种shiro可以理解的形式,shiro就可以依次提供容易理解的Subject程序API而不管有多少数据源或者程序中你的数据如何组织。
Realm 通常和数据源如数据库、LDAP目录、文件系统或者其它类似的数据源是一对一的关系,所以,可以用数据源相应的API如JDBC、File
IO、 Hibernate 或者JPA以及其它的API来实现Realm接口,从而获取授权的相关数据(角色、权限等)。
realm本质上就是一个指定安全的DAO。
因为大部分这类数据源通常都会同时存储认证数据(如密码)和授权数据(如角色和权限),所以每一个Shiro Realm都可以同时执行认证和授权操作。
Realm Configuration
如果使用shiro的ini配置文件,你可以在[main]区域内像配置其它对象一样定义和引用Realms,但是Realm在secrityManager上的配置有两种方式:明确方式和隐含方式。
明确指定
在迄今所知的INI配置文件的相关知识中,这是一种显示的配置方式。在定义一个或多个Realm后,再将它们在securityManager上进行统一配置。
例如:
fooRealm = com.company.foo.Realm
barRealm = com.company.another.Realm
bazRealm = com.company.baz.Realm
securityManager.realms = $fooRealm, $barRealm, $bazRealm
明确设置是确定性的,你可以非常确切地知道哪个realm在使用并且知道它们执行的顺序。可以查看认证章节的Authentication Sequence
了解Realm的执行顺序的影响效果。
不明确指定
不是首选的
不明确指定时,如果你改变了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定义的顺序直接影响其在验证和授权尝试中执行的顺序,如果你改变了定义顺序,你必须改变Authenticator的验证序列函数。
因此,为了确保行为的确定性,我们建议使用明确指定的方式代替不明确的指定方式。
Realm验证
一旦理解了shiro主要的认证流程,你应该知道非常重要的一点:尝试进行认证时Realm和Authenticator之间究竟发生了什么。
支持AuthenticationTokens
正如在验证序列中提到的,在一个realm执行一个验证尝试之前,它的“支持”方法被调用。只有在返回值为true的时候它的getAuthenticationInfo(token)
方法才会执行。
通常情况下,一个realm将检查提交的令牌类型(接口或类)确定自己是否可以处理它,例如,一个处理生物特性数据的Realm可能一点也不理解UsernamePasswordTokens,在这种情况下它将从支持函数中返回false。
处理支持的验证令牌
如果一个Realm支持提交的验证令牌,验证将调用Realm的getAuthenticationInfo(token)方法,这是Realm使用后台数据进行验证的一次有效尝试,顺序执行以下动作:
1.检查主要身份令牌(用户身份信息);
2.基于主要信息,在数据源中查找对应的用户数据;
3.确定令牌支持的凭证数据和存储的数据相符;
4.如果凭证相符,返回一个AuthenticationInfo实例,里面封装了Shiro可以理解的用户数据。
5.如果证据不符,抛出AuthenticationException
异常。
这是所有Realm getAuthenticationInfo 实现的最高级别工作流,Realm在这个过程中可以自由做自己想做的事情,比如记录日志,修改数据,以及其他,只要对于存储的数据和验证尝试来讲是合理的就行。
仅有一件事情是必须的,如果证据和给定的主要信息匹配,需要返回一个非空的AuthenticationInfo实例,用来表示来自数据源的用户信息。
节约时间
直接实现Realm接口也许需要时间并容易出错,大部分用户选择继承AuthorizingRealm虚拟类,这个类实现了常用的验证和授权工作流,这会节省你的时间而且不易出错。
凭证匹配
在上述realm验证工作流中,一个Realm必须较验Subject提交的凭证(如密码)是否与存储在数据中的证书相匹配,如果匹配,验证成功,系统保留已证实的终端用户身份。
Realm凭证匹配
检查提交的凭证是否与后台存储数据相匹配是每一个Realm的责任而不是Authenticator的责任,每一个Realm都具备与凭证形式及存储密切相关的技能,可以执行详细的证明比对,而Authenticator只是一个普通的工作流组件。
凭证匹配的过程在所有程序中基本上是一样的,通常只是对比数据方式不同。要确保这个过程在必要时是可插拔和可定制的,AuthenticatingRealm以及它的子类支持用CredentialsMatcher来执行一个凭证对比。
在找到用户数据之后,它和提交的 AuthenticationToken一起传递给一个 CredentialsMatcher
,后者用来检查提交的数据和存储的数据是否相匹配。
Shiro某些CredentialsMatcher实现可以使你开始out of the box,比如 SimpleCredentialsMatcher和HashedCredentialsMatcher实现,但如果你想配置一个自定义的实现来完成特定的对比逻辑,你可以这样做:
Realm myRealm = new com.company.shiro.realm.MyRealm();
CredentialsMatcher customMatcher = new com.company.shiro.realm.CustomCredentialsMatcher();
myRealm.setCredentialsMatcher(customMatcher);
或者,使用Shiro的INI配置文件
[main]
...
customMatcher = com.company.shiro.realm.CustomCredentialsMatcher
myRealm = com.company.shiro.realm.MyRealm
myRealm.credentialsMatcher = $customMatcher
...
简单证明匹配
所有Shiro的out-of-the-box Realm默认使用一个 SimpleCredentialsMatcher(简单证明匹配), SimpleCredentialsMatcher对存储的用户凭证和从AuthenticationToken提交的用户凭证直接执行相等的检查。
例如,如果提交了一个UsernamePasswordToken,SimpleCredentialsMatcher检查提交的密码与存储的密码是否完全相等。
SimpleCredentialsMatcher 不仅仅对字符串执行相同对比,它可以对大多数常用类型,如字符串、字符数组、字节数组、文件和输入流等执行对比,查看JavaDoc获取更多的信息。
Hashing凭证:
取代将凭证按它们原始形式存储并执行原始数据的对比,存储终端用户的凭证(如密码)更安全的办法是在存储数据之前,先进行hash运算。
这确保终端用户的凭证不会以他们原始的形式存储,没有人能知道其原始值。与明文原始比较相比这是一种更为安全的做法,有安全意识的程序会更喜欢这种方法。
要支持这种加密的hash策略,Shiro为Realm配置提供了一个HashedCredentialsMatcher实现替代之前的
SimpleCredentialsMatcher。
Hashing 凭证以及hash迭代的好处超出了该Realm文档的范围,可以在HashedCredentialsMatcher JavaDoc更详细地了解这些主要内容。
Hashing以及相符合的匹配
对于一个使用Shiro的程序,如何配置才能简单地做到这些?
Shiro提供了多个HashedCredentialsMatcher子类实现,你必须在你的Realm上配置指定的实现来匹配你的凭证所使用的hash算法。
例发,假设你的程序使用用户名/密码对来进行验证,基于上述hash凭证的好处,你希望当创建用户时以SHA-265方式加密用户的密码,你可以加密用户输入的明文密码并保存加密值:
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.apache.shiro.crypto.RandomNumberGenerator;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
...
//We'll use a Random Number Generator to generate salts.
This
//is much more secure than using a username as a salt or not
//having a salt at all.
Shiro makes this easy.
//
//Note that a normal app would reference an attribute rather
//than create a new RNG every time:
RandomNumberGenerator rng = new SecureRandomNumberGenerator();
Object salt = rng.nextBytes();
//Now hash the plain-text password with the random salt and multiple
//iterations and then Base64-encode the value (requires less space than Hex):
String hashedPasswordBase64 = new Sha256Hash(plainTextPassword, salt, 1024).toBase64();
User user = new User(username, hashedPasswordBase64);
//save the salt with the new account.
The HashedCredentialsMatcher
//will need it later when handling login attempts:
user.setPasswordSalt(salt);
userDAO.create(user);
由于你使用SHA-256加密你的密码,你需要告诉Shiro使用相应的 HashedCredentialsMatcher来检查你的hashing值,在这个例子中,我们为了加强安全创建了一个随机的salt并且执行1024
Hash迭代(查看HashedCredentialsMatcher JAVADoc了解为什么),下面的Shiro INI
配置来做这件工作。
[main]
...
credentialsMatcher = org.apache.shiro.authc.credential.Sha256CredentialsMatcher
# base64 encoding, not hex in this example:
credentialsMatcher.storedCredentialsHexEncoded = false
credentialsMatcher.hashIterations = 1024
# This next property is only needed in Shiro 1.0.
Remove it in 1.1 and later:
credentialsMatcher.hashSalted = true
...
myRealm = com.company.....
myRealm.credentialsMatcher = $credentialsMatcher
...
SaltedAuthenticationInfo
确保正常运行的最后一件要做的事情是你的Realm实现必须返回一个 SaltedAuthenticationInfo
实例而不是普通的AuthenticationInfo,SaltedAuthenticationInfo
接口确保你在创建用户帐户时使用的salt(如上面调用的 user.setPasswordSalt(salt);)能被HashedCredentialsMatcher引用。
HashedCredentialsMatcher需要使用salt来对提交的AuthenticationToken执行相同的hashing技术来对比提交的令牌是否与存储的数据相匹配,所以如果你对用户密码使用salting(你应该这么做),确保你的Realm实现在返回SaltedAuthenticationInfo
实例时引用它。
禁用验证
如果有理由,你不希望某个Realm对某个资源执行验证(或者因为你只想Realm去执行授权检查),你可以完全禁用Realm的验证支持,方法就是在Realm的支持方法中始终返回False,这样,你的realm将在整个验证过程中不再被使用。
当然如果你想验证Subject,至少要配置一个支持AuthenticationTokens
的Realm。
Realm 授权
待决定。
原文地址:http://shiro.apache.org/realm.html
分享到:
相关推荐
Shiro的架构主要包括三个核心组件:Subject、SecurityManager和Realms。 - **Subject**:代表当前用户的安全操作主体,是Shiro与应用交互的主要接口。 - **SecurityManager**:安全的管理者,负责协调Subject和...
2. **Realms**: Realm 是 Shiro 与具体安全数据源(如数据库、LDAP 等)的桥梁,负责从数据源中获取认证和授权信息。 3. **Cryptography**:Shiro 提供了丰富的加密工具,包括密码哈希、消息摘要算法、对称和非...
Apache Shiro 是一个强大且易用的Java安全框架,提供了认证、授权、加密和会话管理功能,可以非常轻松地开发出足够安全的应用。Shiro 不仅可以用于Java Web 应用,也可以用于独立的Java应用。在集成Spring时,Shiro ...
Apache Shiro 是一个强大且易用的 Java 安全框架,提供身份认证、授权、加密和会话管理功能,简化了处理安全性的工作。在本文中,我们将深入探讨 Apache Shiro 的核心概念及其最简单的整合方式。 一、Shiro 的核心...
Apache Shiro是一款强大的Java安全框架,它为应用程序提供了身份验证、授权、会话管理和加密等核心功能。在本文中,我们将深入探讨Apache Shiro的基础配置和代码实现,以帮助你理解如何有效地使用Shiro进行权限控制...
Apache Shiro 是一个强大且易用的Java安全框架,提供了认证、授权、加密和会话管理功能,可以非常轻松地开发出足够安全的应用。张开涛的《跟我学Shiro》是一本深入浅出的教程,旨在帮助读者快速掌握Shiro的核心概念...
Apache Shiro是一个强大的Java安全框架,它...此外,了解并正确配置Shiro的各个组件,如Realms(用于认证和授权的数据源)、Filters(处理HTTP请求的过滤器)和Cryptography(加密工具),是实现高效且安全应用的关键。
首先,Shiro的介绍部分涵盖了基本概念和术语,如“Subject”(主体,可以理解为访问系统的用户),“Realms”(领域,用于连接Shiro和后端安全数据源)等。Shiro的架构设计是基于简单、直观的编程模型,易于理解和...
通过阅读《Apache Shiro_安全框架开发文档.pdf》这份文档,你将深入了解Shiro的架构、核心组件(如Subject、Realms、Session Manager等)、以及如何实现自定义策略。文档还会包含示例代码和最佳实践,帮助你在实际...
Apache Shiro 是一个强大且易用的 Java 安全框架,它提供了认证、授权、加密和会话管理功能,简化了开发人员处理安全问题的过程。本参考手册主要分为以下几个部分,详细介绍了 Apache Shiro 的各个方面。 1. **...
2. **Realms**: Realm是Shiro与应用安全数据源(如数据库)的桥梁,它负责验证凭证并提供角色和权限信息。在我们的demo中,我们需要创建一个自定义Realm来连接到数据源,并实现认证和授权逻辑。 3. **...
Apache Shiro 是一个强大且易用的 Java 安全框架,提供身份认证、授权、会话管理和加密等全面的安全服务。对于开发者来说,通过学习 Shiro 的源码,可以深入理解其内部工作原理,提高安全编程的能力。在这个 Shiro...
Apache Shiro 是一款轻量级的安全框架,专为Java开发者设计,用于实现应用程序的身份认证、授权和会话管理。这个中文开发文档详细介绍了如何在项目中集成和使用Shiro,帮助开发者构建安全的系统。 **1. 什么是Shiro...
Apache Shiro 是一个轻量级的安全认证框架,旨在简化应用程序的安全管理。与更为复杂的 Spring Security 相比,Shiro 提供了更直观、易于理解和使用的认证和授权机制。本文将深入探讨 Shiro 的核心概念和功能,包括 ...
Apache Shiro是一个强大的Java安全框架,它为应用程序提供了身份验证(Authentication)、授权(Authorization)以及会话管理(Session Management)等功能。本课程旨在通过实战演练和项目案例,帮助学习者深入理解...
Apache Shiro 是一个强大且易用的Java安全框架,提供了认证、授权、加密和会话管理功能,可以非常轻松地开发出足够安全的应用。Shiro 不仅可以用于Java Web 应用,也可以在 Java Desktop 或者是其他Java 应用中使用...
### Apache Shiro 配置说明详解 #### 一、引言 Apache Shiro 是一个强大且易用的 Java 安全框架,它提供了认证、授权、加密和会话管理等功能,能够帮助开发者轻松地处理非常复杂的安全问题。本文将重点介绍 Shiro ...
Apache Shiro是一个强大的Java安全框架,它提供了身份验证、授权、加密和会话管理功能,为开发人员构建安全的应用程序提供了一种简单易用的方式。标题提到的"shiro项目基本运行架包以及全部的架包shiro-all.jar"正是...
Apache Shiro是一个强大易用的Java安全框架,提供了认证、授权、加密和会话管理等功能: 认证 – 用户身份识别,常被称为用户“登录”; 授权 – 访问控制; 密码加密 – 保护或隐藏数据防止被偷窥; ...