ApacheShiro开发手册推荐文档.docx

上传人:b****5 文档编号:3427197 上传时间:2022-11-23 格式:DOCX 页数:23 大小:802.39KB
下载 相关 举报
ApacheShiro开发手册推荐文档.docx_第1页
第1页 / 共23页
ApacheShiro开发手册推荐文档.docx_第2页
第2页 / 共23页
ApacheShiro开发手册推荐文档.docx_第3页
第3页 / 共23页
ApacheShiro开发手册推荐文档.docx_第4页
第4页 / 共23页
ApacheShiro开发手册推荐文档.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

ApacheShiro开发手册推荐文档.docx

《ApacheShiro开发手册推荐文档.docx》由会员分享,可在线阅读,更多相关《ApacheShiro开发手册推荐文档.docx(23页珍藏版)》请在冰豆网上搜索。

ApacheShiro开发手册推荐文档.docx

ApacheShiro开发手册推荐文档

ApacheShiro使用手册

(一)Shiro架构介绍2

ApacheShiro使用手册

(二)Shiro认证4

ApacheShiro使用手册(三)Shiro授权7

ApacheShiro使用手册(四)Realm实现14

ApacheShiro使用手册(五)Shiro酉己置说明15

ApacheShiro使用手册

(一)Shiro架构介绍

1什么是Shiro

ApacheShiro是一个强大易用的Java安全框架,提供了认证、授权、加密和会话管理等功能:

认证-用户身份识别,常被称为用户“登录”;

授权-访问控制;

密码加密-保护或隐藏数据防止被偷窥;

会话管理-每用户相关的时间敏感的状态。

对于任何一个应用程序,Shiro都可以提供全面的安全管理服务。

并且相对于其他安全

框架,Shiro要简单的多。

2、Shiro的架构介绍

首先,来了解一下Shiro的三个核心组件:

Subject,SecurityManager和Realms.如下图:

Subject:

即“当前操作用户”。

但是,在Shiro中,Subject这一概念并不仅仅指人,也可以是第三方进程、后台帐户(DaemonAccount)或其他类似事物。

它仅仅意味着“当前跟软件交互的东西”。

但考虑到大多数目的和用途,你可以把它认为是Shiro的“用户”概念。

Subject代表了当前用户的安全操作,SecurityManager则管理所有用户的安全操作。

SecurityManager:

它是Shiro框架的核心,典型的Facade模式,Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务。

Realm:

Realm充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。

也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查

找用户及其权限信息。

从这个意义上讲,Realm实质上是一个安全相关的DAO:

它封装了数据源的连接细节,

并在需要时将相关数据提供给Shiro。

当配置Shiro时,你必须至少指定一个Realm,用于认

证和(或)授权。

配置多个Realm是可以的,但是至少需要一个。

Shiro内置了可以连接大量安全数据源(又名目录)的Realm,如LDAP、关系数据库

(JDBC)、类似INI的文本配置资源以及属性文件等。

如果缺省的Realm不能满足需求,

你还可以插入代表自定义数据源的自己的Realm实现。

Shiro完整架构图:

 

VM/NetworkBounda

除前文所讲Subject、SecurityManager、Realm三个核心组件外,Shiro主要组件还包括:

Authenticator:

认证就是核实用户身份的过程。

这个过程的常见例子是大家都熟悉的“用户/密码”组合。

多数用户在登录软件系统时,通常提供自己的用户名(当事人)和支持他们的密码(证书)。

如果存储在系统中的密码(或密码表示)与用户提供的匹配,他们就被认为通过认证。

Authorizer:

授权实质上就是访问控制-控制用户能够访问应用中的哪些内容,比如

资源、Web页面等等。

SessionManager:

在安全框架领域,ApacheShiro提供了一些独特的东西:

可在任何应用或架构层一致地使用SessionAPI。

即,Shiro为任何应用提供了一个会话编程范式-从小

型后台独立应用到大型集群Web应用。

这意味着,那些希望使用会话的应用开发者,不必

被迫使用Servlet或EJB容器了。

或者,如果正在使用这些容器,开发者现在也可以选择使用在任何层统一一致的会话API,取代Servlet或EJB机制。

CacheManager:

对Shiro的其他组件提供缓存支持。

|

ApacheShiro使用手册

(二)Shiro认证

认证就是验证用户身份的过程。

在认证过程中,用户需要提交实体信息(Principals)和凭

据信息(Credentials)以检验用户是否合法。

最常见的“实体/凭证”组合便是“用户名/密码”组合。

1、Shiro认证过程

a)收集实体/凭据信息

Java代码h滋

1.//Exampleusingmostcommonscenarioofusername/passwordpair:

2.UsernamePasswordTokentoken=newUsernamePasswordToken(username,pass

word);

3.//”RememberMe,built-in:

4.token.setRememberMe(true);

UsernamePasswordToken支持最常见的用户名/密码的认证机制。

同时,由于它实现了

RememberMeAuthenticationToken接口,我们可以通过令牌设置“记住我”的功能。

但是,“已记住”和“已认证”是有区别的:

已记住的用户仅仅是非匿名用户,你可以通过subject.getPrincipals()获取用户信息。

是它并非是完全认证通过的用户,当你访问需要认证用户的功能时,你仍然需要重新提交认

证信息。

这一区别可以参考亚马逊网站,网站会默认记住登录的用户,再次访问网站时,对于非

敏感的页面功能,页面上会显示记住的用户信息,但是当你访问网站账户信息时仍然需要再

次进行登录认证。

b)提交实体/凭据信息

Java代码_

1.SubjectcurrentUser=SecurityUtils.getSubject();

2.currentUser.login(token);

收集了实体/凭据信息之后,我们可以通过SecurityUtils工具类,获取当前的用户,然

后通过调用login方法提交认证。

c)认证处理

Java代码曲

2.

3.

4.

5.

6.

7.

8.

9.

1.try{

currentUser.login(token);

}catch(UnknownAccountExceptionuae){...

}catch(IncorrectCredentialsExceptionice){...

}catch(LockedAccountExceptionlae){...

}catch(ExcessiveAttemptsExceptioneae){...

}...catchyourown...

}catch(AuthenticationExceptionae){

//unexpectederror?

如果login方法执行完毕且没有抛出任何异常信息,那么便认为用户认证通过。

之后在

登出操作可以通过调用

Java代码尉

1.currentUser」ogout();

datestheirsessiontoo.

当执行完登出操作后,

3、认证内部处理机制

应用程序任意地方调用SecurityUtils.getSubject()都可以获取到当前认证通过的用户实例,

使用subject.isAuthenticated()判断用户是否已验证都将返回true.

相反,如果login方法执行过程中抛出异常,那么将认为认证失败。

Shiro有着丰富的层

次鲜明的异常类来描述认证失败的原因,如代码示例。

2、登出操作

subject.logout()来删除你的登录信息,如:

//removesallidentifyinginformationandinvali

Session信息将被清空,subject将被视作为匿名用户。

以上,是Shiro认证在应用程序中的处理过程,下面将详细解说Shiro认证的内部处理

机制。

如上图,我们通过Shiro架构图的认证部分,来说明Shiro认证内部的处理顺序:

A)、应用程序构建了一个终端用户认证信息的AuthenticationToken实例后,调用

Subject.login方法。

B)、Sbuject的实例通常是DelegatingSubject类(或子类)的实例对象,在认证开始时,

会委托应用程序设置的securityManager实例调用securityManager.login(token)方法。

C)、SecurityManager接受到token(令牌)信息后会委托内置的Authenticator的实例(通

常都是ModularRealmAuthenticator类的实例)调用authenticator.authenticate(token).

ModularRealmAuthenticator在认证过程中会对设置的一个或多个Realm实例进行适配,它实

际上为Shiro提供了一个可拔插的认证机制。

D)、如果在应用程序中配置了多个Realm,ModularRealmAuthenticator会根据配置的

AuthenticationStrategy(认证策略)来进行多Realm的认证过程。

在Realm被调用后,AuthenticationStrategy将对每一个Realm的结果作出响应。

(注:

如果应用程序中仅配置了一个Realm,Realm将被直接调用而无需再配置认证策略。

E)、判断每一个Realm是否支持提交的token,如果支持,Realm将调用getAuthenticationlnfo(token);getAuthenticationlnfo方法就是实际认证处理,我们通过覆盖

Realm的doGetAuthenticationlnfo方法来编写我们自定义的认证处理。

4、使用多个Realm的处理机制:

a)Authenticator

默认实现是ModularRealmAuthenticator,它既支持单一Realm也支持多个Realm。

如果仅配置了一个Realm,ModularRealmAuthenticator会直接调用该Realm处理认证信息,如果配置了多个Realm,它会根据认证策略来适配Realm,找到合适的Realm执行认证信息。

自定义Authenticator的配置:

Java代码

1.[main]

2....

3.authenticator=com.foo.bar.CustomAuthenticator

4.securityManager.authenticator=$authenticator

b)Authenticationstrategy(认证策略)

当应用程序配置了多个Realm时,ModularRealmAuthenticator将根据认证策略来判断认

证成功或是失败。

例如,如果只有一个Realm验证成功,而其他Realm验证失败,那么这次认证是否成功呢?

如果大多数的Realm验证成功了,认证是否就认为成功呢?

或者,一个Realm验证

成功后,是否还需要判断其他Realm的结果?

认证策略就是根据应用程序的需要对这些问

题作出决断。

认证策略是一个无状态的组件,在认证过程中会经过4次的调用:

在所有Realm被调用之前

在调用Realm的getAuthenticationlnfo方法之前在调用Realm的getAuthenticationlnfo方法之后在所有Realm被调用之后

认证策略的另外一项工作就是聚合所有Realm的结果信息封装至一个Authenticationlnfo实例中,并将此信息返回,以此作为Subject的身份信息。

Shiro有3中认证策略的具体实现:

AtLeastOneSuccessfulStrategy

只要有一个(或更多)的Realm验证成功,那么认证将被视为

成功

FirstSuccessfulStrategy

第一个Realm验证成功,整体认证将被视为成功,且后续

Realm将被忽略

AllSuccessfulStrategy

所有Realm成功,认证才视为成功

ModularRealmAuthenticator内置的认证策略默认实现是AtLeastOneSuccessfulStrategy

方式,因为这种方式也是被广泛使用的一种认证策略。

当然,你也可以通过配置文件定义你

需要的策略,如:

Java代码卜色

1.[main]

2....

3.authcStrategy=org.apache.shiro.authc.pam.FirstSuccessfulStrategy

4.securityManager.authenticator.authenticationStrategy=$authcStrategy

5....

c)Realm的顺序

由刚才提到的认证策略,可以看到Realm在ModularRealmAuthenticator里面的顺

序对认证是有影响的。

ModularRealmAuthenticator会读取配置在SecurityManager里的

Realm。

当执行认证是,它会遍历Realm集合,对所有支持提交的token的Realm调用

getAuthenticationlnfo。

因此,如果Realm的顺序对你使用的认证策略结果有影响,那么你应该在配置文

件中明确定义Realm的顺序,如:

Java代码尉

1.blahRealm=pany.blah.Realm

2....

3.fooRealm=pany.foo.Realm

4....

5.barRealm=pany.another.Realm

6.

7.securityManager.realms=$fooRealm,$barRealm,$blahRealm

ApacheShiro使用手册(三)Shiro授权

授权即访问控制,它将判断用户在应用程序中对资源是否拥有相应的访问权限。

女口,判

断一个用户有查看页面的权限,编辑数据的权限,拥有某一按钮的权限,以及是否拥有打印的权限等等。

1、授权的三要素

授权有着三个核心元素:

权限、角色和用户。

i.权限

权限是ApacheShiro安全机制最核心的元素。

它在应用程序中明确声明了被允许的行为和表现。

一个格式良好好的权限声明可以清晰表达出用户对该资源拥有的权限。

大多数的资源会支持典型的CRUD操作(create,read,update,delete),但是任何操作建立在特定的资源上才是有意义的。

因此,权限声明的根本思想就是建立在资

源以及操作上。

而我们通过权限声明仅仅能了解这个权限可以在应用程序中做些什么,而不能

确定谁拥有此权限。

于是,我们就需要在应用程序中对用户和权限建立关联。

通常的做法就是将权限分配给某个角色,然后将这个角色关联一个或多个用户。

ii.权限声明及粒度

Shiro权限声明通常是使用以冒号分隔的表达式。

就像前文所讲,一个权限表达式可以清晰的指定资源类型,允许的操作,可访问的数据。

同时,Shiro权限表

达式支持简单的通配符,可以更加灵活的进行权限设置。

下面以实例来说明权限表达式。

可查询用户数据

User:

view

可查询或编辑用户数据

User:

view,edit

可对用户数据进行所有操作

User:

*或user

可编辑id为123的用户数据

User:

edit:

123

iii.角色

Shiro支持两种角色模式:

1、传统角色:

一个角色代表着一系列的操作,当需要对某一操作进行授权验证时,只需判断是否是该角色即可。

这种角色权限相对简单、模糊,不利于扩展。

2、权限角色:

一个角色拥有一个权限的集合。

授权验证时,需要判断当前角

色是否拥有该权限。

这种角色权限可以对该角色进行详细的权限描述,适合更复杂

的权限设计。

下面将详细描述对两种角色模式的授权实现。

2、授权实现

Shiro支持三种方式实现授权过程:

编码实现

注解实现

JSPTaglig实现

1.基于编码的授权实现

1.1基于传统角色授权实现当需要验证用户是否拥有某个角色时,可以调用Subject实例的

hasRole*方法验证。

Java代码彪

1.SubjectcurrentUser=SecurityUtils.getSubject();

2.if(currentUser.hasRole("administrator")){

3.//showtheadminbutton

4.}else{

5.//don'tshowthebutton?

Greyitout?

6.}

相关验证方法如下:

1—

Subject方法

描述

hasRole(StringroleName)

当用户拥有指定角色时,返回true

hasRoles(ListroleNames)

按照列表顺序返回相应的一个boolean值数

hasAIIRoles(Collectio*String>roleNames)如果用户拥有所有指定角色时,返回true

断言支持

Shiro还支持以断言的方式进行授权验证。

断言成功,不返回任何值,程序继续执行;断言失败时,将抛出异常信息。

使用断言,可以使我们的代码更加简洁。

Java代码

1.SubjectcurrentUser=SecurityUtils.getSubject();

2.//guaranteethatthecurrentuserisabanktellerand

3.//thereforeallowedtoopentheaccount:

4.currentUser.checkRole("bankTeller");

5.openBankAccount();

断言的相关方法:

Subject方法

描述

checkRole(StringroleName)

断言用户是否拥有指定角色

checkRoles(CollectionroleNames)

断言用户是否拥有所有指定角色

checkRoles(String...roleNames)

对上一方法的方法重载

1.2基于权限角色授权实现」

相比传统角色模式,基于权限的角色模式耦合性要更低些,它不会因角色的改

变而对源代码进行修改,因此,基于权限的角色模式是更好的访问控制方式。

它的代码实现有以下几种实现方式:

1.2.1基于权限对象的实现

创建org.apache.shiro.authz.Permission的实例,将该实例对象作为参数传

递给

Subject.isPermitted()进行验证。

Java代码

1.PermissionprintPermission=newPrinterPermission(

jet4400n","print");

"laser

2.SubjectcurrentUser=SecurityUtils.getSubject();

3.if

(currentUser.isPermitted(printPermission)){

4.

//showthePrintbutton

5.}

else{

6.

//don'tshowthebutton?

Greyitout?

7.}

8.PermissionprintPermission=newPrinterPermission(

jet4400n","print");

9.SubjectcurrentUser=SecurityUtils.getSubject();

"laser

10.

if(currentUser.isPermitted(printPermission)){

11.

//showthePrintbutton

12.

}else{

13.

//don'tshowthebutton?

Greyitout?

14.

}

相关方法如下:

Subject方法

~1

描述

isPermitted(Permissionp)

Subject拥有制定权限时,返回treu

isPermitted(Listperms)

返回对应权限的boolean数组

isPermittedAII(Collectionperms)

Subject拥有所有制定权限时,返回true

1.2.2基于字符串的实现相比笨重的基于对象的实现方式,基于字符串的实现便显得更加简洁。

Java代码

1.SubjectcurrentUser=SecurityUtils.getSubject();

2.if(currentUser.isPermitted("printer:

print:

laserjet4400n"

)){

3.//showthePrintbutton

4.}else{

5.//don'tshowthebutton?

Greyitout?

6.}

使用冒号分隔的权限表达式是org.apache.shiro.authz.permission.WildcardPermission默

认支持的实现方式。

这里分别代表了资源类型:

操作:

资源ID

类似基于对象的实现相关方法,基于字符串的实现相关方法:

isPermitted(Stringperm)、isPermitted(String...perms)、isPermittedAII(String...perms)基于权限对象的断言实现

Java代码*

1.SubjectcurrentUser=SecurityUtils.getSubject();

2.//guaranteethatthecurrentuserispermitted

3.//toopenabankaccount:

4.Permissionp=newAccountPermission("open");

5.currentUser.checkPermission(p);

6.openBankAccount();

基于字符串的断言实现

Java代码

1.SubjectcurrentUser=SecurityUtils.getSubject();

2.//guaranteethatthecurrentuserispermitted

3.//toopenabankaccount:

4.currentUser.checkPermission("account:

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 学科竞赛

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1