Shiro用户手册文档格式.docx
- 文档编号:21828022
- 上传时间:2023-02-01
- 格式:DOCX
- 页数:19
- 大小:398.30KB
Shiro用户手册文档格式.docx
《Shiro用户手册文档格式.docx》由会员分享,可在线阅读,更多相关《Shiro用户手册文档格式.docx(19页珍藏版)》请在冰豆网上搜索。
这个过程的常见例子是大家都熟悉的“用户/密码”组合。
多数用户在登录软件系统时,通常提供自己的用户名(当事人)和支持他们的密码(证书)。
如果存储在系统中的密码(或密码表示)与用户提供的匹配,他们就被认为通过认证。
Authorizer:
授权实质上就是访问控制-控制用户能够访问应用中的哪些内容,比如资源、Web页面等等。
SessionManager:
在安全框架领域,ApacheShiro提供了一些独特的东西:
可在任何应用或架构层一致地使用SessionAPI。
即,Shiro为任何应用提供了一个会话编程范式-从小型后台独立应用到大型集群Web应用。
这意味着,那些希望使用会话的应用开发者,不必被迫使用Servlet或EJB容器了。
或者,如果正在使用这些容器,开发者现在也可以选择使用在任何层统一一致的会话API,取代Servlet或EJB机制。
CacheManager:
对Shiro的其他组件提供缓存支持。
✧Shiro认证
认证就是验证用户身份的过程。
在认证过程中,用户需要提交实体信息(Principals)和凭据信息(Credentials)以检验用户是否合法。
最常见的“实体/凭证”组合便是“用户名/密码”组合。
一、Shiro认证过程
1、收集实体/凭据信息
Java代码
1.//Example
using
most
common
scenario
of
username/password
pair:
2.UsernamePasswordToken
token
=
new
UsernamePasswordToken(username,
password);
3.//”Remember
Me”
built-in:
4.token.setRememberMe(true);
UsernamePasswordToken支持最常见的用户名/密码的认证机制。
同时,由于它实现了RememberMeAuthenticationToken接口,我们可以通过令牌设置“记住我”的功能。
但是,“已记住”和“已认证”是有区别的:
已记住的用户仅仅是非匿名用户,你可以通过subject.getPrincipals()获取用户信息。
但是它并非是完全认证通过的用户,当你访问需要认证用户的功能时,你仍然需要重新提交认证信息。
这一区别可以参考亚马逊网站,网站会默认记住登录的用户,再次访问网站时,对于非敏感的页面功能,页面上会显示记住的用户信息,但是当你访问网站账户信息时仍然需要再次进行登录认证。
2、提交实体/凭据信息
1.Subject
currentUser
SecurityUtils.getSubject();
2.currentUser.login(token);
收集了实体/凭据信息之后,我们可以通过SecurityUtils工具类,获取当前的用户,然后通过调用login方法提交认证。
3、认证处理
1.try
{
2.
currentUser.login(token);
3.}
catch
(
UnknownAccountException
uae
)
...
4.}
IncorrectCredentialsException
ice
5.}
LockedAccountException
lae
6.}
ExcessiveAttemptsException
eae
7.}
your
own
8.}
AuthenticationException
ae
9.
//unexpected
error?
10.}
如果login方法执行完毕且没有抛出任何异常信息,那么便认为用户认证通过。
之后在应用程序任意地方调用SecurityUtils.getSubject()都可以获取到当前认证通过的用户实例,使用subject.isAuthenticated()判断用户是否已验证都将返回true.
相反,如果login方法执行过程中抛出异常,那么将认为认证失败。
Shiro有着丰富的层次鲜明的异常类来描述认证失败的原因,如代码示例。
二、登出操作
登出操作可以通过调用subject.logout()来删除你的登录信息,如:
1.currentUser.logout();
//removes
all
identifying
information
and
invalidates
their
session
too.
当执行完登出操作后,Session信息将被清空,subject将被视作为匿名用户。
三、认证内部处理机制
以上,是Shiro认证在应用程序中的处理过程,下面将详细解说Shiro认证的内部处理机制。
如上图,我们通过Shiro架构图的认证部分,来说明Shiro认证内部的处理顺序:
1、应用程序构建了一个终端用户认证信息的AuthenticationToken实例后,调用Subject.login方法。
2、Sbuject的实例通常是DelegatingSubject类(或子类)的实例对象,在认证开始时,会委托应用程序设置的securityManager实例调用securityManager.login(token)方法。
3、SecurityManager接受到token(令牌)信息后会委托内置的Authenticator的实例(通常都是ModularRealmAuthenticator类的实例)调用authenticator.authenticate(token).ModularRealmAuthenticator在认证过程中会对设置的一个或多个Realm实例进行适配,它实际上为Shiro提供了一个可拔插的认证机制。
4、如果在应用程序中配置了多个Realm,ModularRealmAuthenticator会根据配置的AuthenticationStrategy(认证策略)来进行多Realm的认证过程。
在Realm被调用后,AuthenticationStrategy将对每一个Realm的结果作出响应。
注:
如果应用程序中仅配置了一个Realm,Realm将被直接调用而无需再配置认证策略。
5、判断每一个Realm是否支持提交的token,如果支持,Realm将调用getAuthenticationInfo(token);
getAuthenticationInfo方法就是实际认证处理,我们通过覆盖Realm的doGetAuthenticationInfo方法来编写我们自定义的认证处理。
四、使用多个Realm的处理机制:
1、Authenticator
默认实现是ModularRealmAuthenticator,它既支持单一Realm也支持多个Realm。
如果仅配置了一个Realm,ModularRealmAuthenticator会直接调用该Realm处理认证信息,如果配置了多个Realm,它会根据认证策略来适配Realm,找到合适的Realm执行认证信息。
自定义Authenticator的配置:
1.[main]
2....
3.authenticator
com.foo.bar.CustomAuthenticator
4.securityManager.authenticator
$authenticator
2、AuthenticationStrategy(认证策略)
当应用程序配置了多个Realm时,ModularRealmAuthenticator将根据认证策略来判断认证成功或是失败。
例如,如果只有一个Realm验证成功,而其他Realm验证失败,那么这次认证是否成功呢?
如果大多数的Realm验证成功了,认证是否就认为成功呢?
或者,一个Realm验证成功后,是否还需要判断其他Realm的结果?
认证策略就是根据应用程序的需要对这些问题作出决断。
认证策略是一个无状态的组件,在认证过程中会经过4次的调用:
∙在所有Realm被调用之前
∙在调用Realm的getAuthenticationInfo方法之前
∙在调用Realm的getAuthenticationInfo方法之后
∙在所有Realm被调用之后
认证策略的另外一项工作就是聚合所有Realm的结果信息封装至一个AuthenticationInfo实例中,并将此信息返回,以此作为Subject的身份信息。
Shiro有3中认证策略的具体实现:
AtLeastOneSuccessfulStrategy
只要有一个(或更多)的Realm验证成功,那么认证将被视为成功
FirstSuccessfulStrategy
第一个Realm验证成功,整体认证将被视为成功,且后续Realm将被忽略
AllSuccessfulStrategy
所有Realm成功,认证才视为成功
ModularRealmAuthenticator内置的认证策略默认实现是AtLeastOneSuccessfulStrategy方式,因为这种方式也是被广泛使用的一种认证策略。
当然,你也可以通过配置文件定义你需要的策略,如:
3.authcStrategy
org.apache.shiro.authc.pam.FirstSuccessfulStrategy
4.securityManager.authenticator.authenticationStrategy
$authcStrategy
5....
3、Realm的顺序
由刚才提到的认证策略,可以看到Realm在ModularRealmAuthenticator里面的顺序对认证是有影响的。
ModularRealmAuthenticator会读取配置在SecurityManager里的Realm。
当执行认证是,它会遍历Realm集合,对所有支持提交的token的Realm调用getAuthenticationInfo。
因此,如果Realm的顺序对你使用的认证策略结果有影响,那么你应该在配置文件中明确定义Realm的顺序,如:
1.blahRealm
pany.blah.Realm
3.fooRealm
pany.foo.Realm
4....
5.barRealm
pany.another.Realm
6.
7.securityManager.realms
$fooRealm,
$barRealm,
$blahRealm
✧Shiro授权
授权即访问控制,它将判断用户在应用程序中对资源是否拥有相应的访问权限。
如,判断一个用户有查看页面的权限,编辑数据的权限,拥有某一按钮的权限,以及是否拥有打印的权限等等。
一、授权的三要素
授权有着三个核心元素:
权限、角色和用户。
权限
权限是ApacheShiro安全机制最核心的元素。
它在应用程序中明确声明了被允许的行为和表现。
一个格式良好好的权限声明可以清晰表达出用户对该资源拥有的权限。
大多数的资源会支持典型的CRUD操作(create,read,update,delete),但是任何操作建立在特定的资源上才是有意义的。
因此,权限声明的根本思想就是建立在资源以及操作上。
而我们通过权限声明仅仅能了解这个权限可以在应用程序中做些什么,而不能确定谁拥有此权限。
于是,我们就需要在应用程序中对用户和权限建立关联。
通常的做法就是将权限分配给某个角色,然后将这个角色关联一个或多个用户。
权限声明及粒度
Shiro权限声明通常是使用以冒号分隔的表达式。
就像前文所讲,一个权限表达式可以清晰的指定资源类型,允许的操作,可访问的数据。
同时,Shiro权限表达式支持简单的通配符,可以更加灵活的进行权限设置。
下面以实例来说明权限表达式。
可查询用户数据
User:
view
可查询或编辑用户数据
view,edit
可对用户数据进行所有操作
*或user
可编辑id为123的用户数据
edit:
123
角色
Shiro支持两种角色模式:
1、传统角色:
一个角色代表着一系列的操作,当需要对某一操作进行授权验证时,只需判断是否是该角色即可。
这种角色权限相对简单、模糊,不利于扩展。
2、权限角色:
一个角色拥有一个权限的集合。
授权验证时,需要判断当前角色是否拥有该权限。
这种角色权限可以对该角色进行详细的权限描述,适合更复杂的权限设计。
下面将详细描述对两种角色模式的授权实现。
二、授权实现
Shiro支持三种方式实现授权过程:
∙编码实现
∙注解实现
∙JSPTaglig实现
1、基于编码的授权实现
1.1基于传统角色授权实现
当需要验证用户是否拥有某个角色时,可以调用Subject实例的hasRole*方法验证。
2.if
(currentUser.hasRole("
administrator"
))
3.
//show
the
admin
button
else
5.
//don'
t
show
button?
Grey
it
out?
相关验证方法如下:
Subject方法
描述
hasRole(StringroleName)
当用户拥有指定角色时,返回true
hasRoles(List<
String>
roleNames)
按照列表顺序返回相应的一个boolean值数组
hasAllRoles(Collection<
如果用户拥有所有指定角色时,返回true
断言支持
Shiro还支持以断言的方式进行授权验证。
断言成功,不返回任何值,程序继续执行;
断言失败时,将抛出异常信息。
使用断言,可以使我们的代码更加简洁。
2.//guarantee
that
current
user
is
a
bank
teller
3.//therefore
allowed
to
open
account:
4.currentUser.checkRole("
bankTeller"
);
5.openBankAccount();
断言的相关方法:
checkRole(StringroleName)
断言用户是否拥有指定角色
checkRoles(Collection<
断言用户是否拥有所有指定角色
checkRoles(String...roleNames)
对上一方法的方法重载
1.2基于权限角色授权实现
相比传统角色模式,基于权限的角色模式耦合性要更低些,它不会因角色的改变而对源代码进行修改,因此,基于权限的角色模式是更好的访问控制方式。
它的代码实现有以下几种实现方式:
1、基于权限对象的实现
创建org.apache.shiro.authz.Permission的实例,将该实例对象作为参数传递给Subject.isPermitted()进行验证。
1.Permission
printPermission
PrinterPermission("
laserjet4400n"
"
print"
2.Subject
3.if
(currentUser.isPermitted(printPermission))
4.
8.Permission
9.Subject
10.if
11.
12.}
13.
14.}
相关方法如下:
isPermitted(Permissionp)
Subject拥有制定权限时,返回treu
isPermitted(List<
Permission>
perms)
返回对应权限的boolean数组
isPermittedAll(Collection<
Subject拥有所有制定权限时,返回true
2、基于字符串的实现
相比笨重的基于对象的实现方式,基于字符串的实现便显得更加简洁。
(currentUser.isPermitted("
printer:
print:
使用冒号分隔的权限表达式是org.apache.shiro.authz.permission.WildcardPermission默认支持的实现方式。
这里分别代表了资源类型:
操作:
资源ID
类似基于对象的实现相关方法,基于字符串的实现相关方法:
isPermitted(Stringperm)、isPermitted(String...perms)、isPermittedAll(String...perms)
基于权限对象的断言实现
permitted
3.//to
4.Permission
p
AccountPermission("
open"
5.currentUser.checkPermission(p);
6.openBankAccount();
基于字符串的断言实现
4.currentUser.checkPermission("
断言实现的相关方法
说明
checkPermission(Permissionp)
断言用户是否拥有制定权限
checkPermission(Stringperm)
checkPermissions(Collect
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Shiro 用户手册