`
kdboy
  • 浏览: 761185 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Apache Shiro 使用手册(三)Shiro 授权

阅读更多
授权即访问控制,它将判断用户在应用程序中对资源是否拥有相应的访问权限。
如,判断一个用户有查看页面的权限,编辑数据的权限,拥有某一按钮的权限,以及是否拥有打印的权限等等。

一、授权的三要素

授权有着三个核心元素:权限、角色和用户。

权限
权限是Apache Shiro安全机制最核心的元素。它在应用程序中明确声明了被允许的行为和表现。一个格式良好好的权限声明可以清晰表达出用户对该资源拥有的权限。
大多数的资源会支持典型的CRUD操作(create,read,update,delete),但是任何操作建立在特定的资源上才是有意义的。因此,权限声明的根本思想就是建立在资源以及操作上。
而我们通过权限声明仅仅能了解这个权限可以在应用程序中做些什么,而不能确定谁拥有此权限。
于是,我们就需要在应用程序中对用户和权限建立关联。
通常的做法就是将权限分配给某个角色,然后将这个角色关联一个或多个用户。

权限声明及粒度
Shiro权限声明通常是使用以冒号分隔的表达式。就像前文所讲,一个权限表达式可以清晰的指定资源类型,允许的操作,可访问的数据。同时,Shiro权限表达式支持简单的通配符,可以更加灵活的进行权限设置。
下面以实例来说明权限表达式。
可查询用户数据
User:view
可查询或编辑用户数据
User:view,edit
可对用户数据进行所有操作
User:* 或 user
可编辑id为123的用户数据
User:edit:123

角色
Shiro支持两种角色模式:
1、传统角色:一个角色代表着一系列的操作,当需要对某一操作进行授权验证时,只需判断是否是该角色即可。这种角色权限相对简单、模糊,不利于扩展。
2、权限角色:一个角色拥有一个权限的集合。授权验证时,需要判断当前角色是否拥有该权限。这种角色权限可以对该角色进行详细的权限描述,适合更复杂的权限设计。
下面将详细描述对两种角色模式的授权实现。

二、授权实现

Shiro支持三种方式实现授权过程:
  • 编码实现
  • 注解实现
  • JSP Taglig实现
1、基于编码的授权实现

1.1基于传统角色授权实现
当需要验证用户是否拥有某个角色时,可以调用Subject 实例的hasRole*方法验证。
Subject currentUser = SecurityUtils.getSubject();
if (currentUser.hasRole("administrator")) {
    //show the admin button
} else {
    //don't show the button?  Grey it out?
}

相关验证方法如下:
Subject方法描述
hasRole(String roleName)当用户拥有指定角色时,返回true
hasRoles(List<String> roleNames)按照列表顺序返回相应的一个boolean值数组
hasAllRoles(Collection<String> roleNames)如果用户拥有所有指定角色时,返回true

断言支持
Shiro还支持以断言的方式进行授权验证。断言成功,不返回任何值,程序继续执行;断言失败时,将抛出异常信息。使用断言,可以使我们的代码更加简洁。
Subject currentUser = SecurityUtils.getSubject();
//guarantee that the current user is a bank teller and
//therefore allowed to open the account:
currentUser.checkRole("bankTeller");
openBankAccount();

断言的相关方法:
Subject方法描述
checkRole(String roleName)断言用户是否拥有指定角色
checkRoles(Collection<String> roleNames)断言用户是否拥有所有指定角色
checkRoles(String... roleNames)对上一方法的方法重载

1.2 基于权限角色授权实现
相比传统角色模式,基于权限的角色模式耦合性要更低些,它不会因角色的改变而对源代码进行修改,因此,基于权限的角色模式是更好的访问控制方式。
它的代码实现有以下几种实现方式:
1、基于权限对象的实现
创建org.apache.shiro.authz.Permission的实例,将该实例对象作为参数传递给Subject.isPermitted()进行验证。
Permission printPermission = new PrinterPermission("laserjet4400n", "print");
Subject currentUser = SecurityUtils.getSubject();
if (currentUser.isPermitted(printPermission)) {
    //show the Print button
} else {
    //don't show the button?  Grey it out?
}
Permission printPermission = new PrinterPermission("laserjet4400n", "print");
Subject currentUser = SecurityUtils.getSubject();
if (currentUser.isPermitted(printPermission)) {
    //show the Print button
} else {
    //don't show the button?  Grey it out?
}

相关方法如下:
Subject方法描述
isPermitted(Permission p)Subject拥有制定权限时,返回treu
isPermitted(List<Permission> perms)返回对应权限的boolean数组
isPermittedAll(Collection<Permission> perms)Subject拥有所有制定权限时,返回true

2、 基于字符串的实现
相比笨重的基于对象的实现方式,基于字符串的实现便显得更加简洁。
Subject currentUser = SecurityUtils.getSubject();
if (currentUser.isPermitted("printer:print:laserjet4400n")) {
    //show the Print button
} else {
    //don't show the button?  Grey it out?
}

使用冒号分隔的权限表达式是org.apache.shiro.authz.permission.WildcardPermission 默认支持的实现方式。
这里分别代表了 资源类型:操作:资源ID

类似基于对象的实现相关方法,基于字符串的实现相关方法:
isPermitted(String perm)、isPermitted(String... perms)、isPermittedAll(String... perms)

基于权限对象的断言实现
Subject currentUser = SecurityUtils.getSubject();
//guarantee that the current user is permitted
//to open a bank account:
Permission p = new AccountPermission("open");
currentUser.checkPermission(p);
openBankAccount();

基于字符串的断言实现
Subject currentUser = SecurityUtils.getSubject();
//guarantee that the current user is permitted
//to open a bank account:
currentUser.checkPermission("account:open");
openBankAccount();

断言实现的相关方法
Subject方法说明
checkPermission(Permission p)断言用户是否拥有制定权限
checkPermission(String perm)断言用户是否拥有制定权限
checkPermissions(Collection<Permission> perms)断言用户是否拥有所有指定权限
checkPermissions(String... perms)断言用户是否拥有所有指定权限

2、基于注解的授权实现
Shiro注解支持AspectJ、Spring、Google-Guice等,可根据应用进行不同的配置。

相关的注解:
@ RequiresAuthentication
可以用户类/属性/方法,用于表明当前用户需是经过认证的用户。
@RequiresAuthentication
public void updateAccount(Account userAccount) {
    //this method will only be invoked by a 
    //Subject that is guaranteed authenticated
    ...
}

@ RequiresGuest
表明该用户需为”guest”用户

@ RequiresPermissions
当前用户需拥有制定权限
@RequiresPermissions("account:create")
public void createAccount(Account account) {
    //this method will only be invoked by a Subject
    //that is permitted to create an account
    ...
}

@RequiresRoles
当前用户需拥有制定角色

@ RequiresUser
当前用户需为已认证用户或已记住用户

3、基于JSP  TAG的授权实现
Shiro提供了一套JSP标签库来实现页面级的授权控制。
在使用Shiro标签库前,首先需要在JSP引入shiro标签:
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>

下面一一介绍Shiro的标签:
guest标签
验证当前用户是否为“访客”,即未认证(包含未记住)的用户
<shiro:guest>
    Hi there!  Please <a href="login.jsp">Login</a> or <a href="signup.jsp">Signup</a> today!
</shiro:guest>

user标签
认证通过或已记住的用户
<shiro:user>
    Welcome back John!  Not John? Click <a href="login.jsp">here<a> to login.
</shiro:user>

authenticated标签
已认证通过的用户。不包含已记住的用户,这是与user标签的区别所在。
<shiro:authenticated>
    <a href="updateAccount.jsp">Update your contact information</a>.
</shiro:authenticated>

notAuthenticated标签
未认证通过用户,与authenticated标签相对应。与guest标签的区别是,该标签包含已记住用户。
<shiro:notAuthenticated>
    Please <a href="login.jsp">login</a> in order to update your credit card information.
</shiro:notAuthenticated>

principal 标签
输出当前用户信息,通常为登录帐号信息
Hello, <shiro:principal/>, how are you today?

hasRole标签
验证当前用户是否属于该角色
<shiro:hasRole name="administrator">
    <a href="admin.jsp">Administer the system</a>
</shiro:hasRole>

lacksRole标签
与hasRole标签逻辑相反,当用户不属于该角色时验证通过
<shiro:lacksRole name="administrator">
    Sorry, you are not allowed to administer the system.
</shiro:lacksRole>

hasAnyRole标签
验证当前用户是否属于以下任意一个角色。
<shiro:hasAnyRoles name="developer, project manager, administrator">
    You are either a developer, project manager, or administrator.
</shiro:lacksRole>

hasPermission标签
验证当前用户是否拥有制定权限
<shiro:hasPermission name="user:create">
    <a href="createUser.jsp">Create a new User</a>
</shiro:hasPermission>

lacksPermission标签
与hasPermission标签逻辑相反,当前用户没有制定权限时,验证通过
<shiro:hasPermission name="user:create">
    <a href="createUser.jsp">Create a new User</a>
</shiro:hasPermission>


三、Shiro授权的内部处理机制

1、在应用程序中调用授权验证方法(Subject的isPermitted*或hasRole*等)
2、Sbuject的实例通常是DelegatingSubject类(或子类)的实例对象,在认证开始时,会委托应用程序设置的securityManager实例调用相应的isPermitted*或hasRole*方法。
3、接下来SecurityManager会委托内置的Authorizer的实例(默认是ModularRealmAuthorizer 类的实例,类似认证实例,它同样支持一个或多个Realm实例认证)调用相应的授权方法。
4、每一个Realm将检查是否实现了相同的 Authorizer 接口。然后,将调用Reaml自己的相应的授权验证方法。

当使用多个Realm时,不同于认证策略处理方式,授权处理过程中:
1、当调用Realm出现异常时,将立即抛出异常,结束授权验证。
2、只要有一个Realm验证成功,那么将认为授权成功,立即返回,结束认证。
  • 大小: 82 KB
25
1
分享到:
评论
4 楼 yiml797 2014-10-15  
楼主有demo吗?给个最好给个spring  mvc的demo啊,谢谢了
3 楼 xining 2014-07-22  
权限的声明User:view,Customer:edit等, 前边的对象 User,Customer 是否要跟实例类名称一致, 还是随意定义??
2 楼 ylmotol7 2013-09-14  
aij 写道
shiro 在权限声明的时候
是不是一定要User:view,Customer:edit等等这样的写法?
比如随便一个单词作为权限是不是也可以,比如 直接只写一个userEdit,customerEdit?

可以自定义的,不需要那么写,stringpermission对应的就是字符串
1 楼 aij 2013-06-20  
shiro 在权限声明的时候
是不是一定要User:view,Customer:edit等等这样的写法?
比如随便一个单词作为权限是不是也可以,比如 直接只写一个userEdit,customerEdit?

相关推荐

    Apache_Shiro参考手册中文版.zip

    Apache_Shiro参考手册中文版 Introduction to Apache Shiro What is Apache Shiro? Apache Shiro 是一个强大而灵活的开源安全框架,它干净利落地处理身份认证,授权,企业会话管理和加密。 Apache Shiro 的首要目标...

    Apache_Shiro_使用手册(一)Shiro架构介绍

    ### Apache Shiro 使用手册(一)Shiro架构介绍 #### 一、Shiro简介 Apache Shiro 是一款功能强大且易于使用的 Java 安全框架,它提供了多种安全相关的功能和服务,包括但不限于认证、授权、加密和会话管理。相较...

    Apache Shiro使用手册 共22页.pdf

    Apache Shiro 使用手册 Apache Shiro 是一个强大易用的 Java 安全框架,提供了认证、授权、加密和会话管理等功能。Shiro 的架构主要包括三个核心组件:Subject、SecurityManager 和 Realm。 1. 认证...

    Apache Shiro中文版使用手册

    ### Apache Shiro 使用手册知识点详解 #### 一、Apache Shiro 概述 **1.1 什么是 Apache Shiro** Apache Shiro 是一款强大的 Java 安全框架,它集成了认证、授权、加密和会话管理等功能。这些功能使得 Shiro 成为...

    Apache_Shiro参考手册中文版_shiro_

    通过阅读《Apache Shiro参考手册中文版》PDF,你可以深入了解每个功能的详细用法,包括如何配置Shiro,如何创建自定义的 Realm,以及如何在代码中使用Subject、Session和Cache等核心概念。手册还会涵盖实际案例和...

    Apache Shiro 中文手册

    通过阅读"Apache Shiro 中文手册",你将能够全面了解Shiro的工作原理,学习如何在项目中配置和使用它,从而提高你的应用安全性,并实现高效的身份验证和授权机制。无论是初学者还是有经验的开发者,这都是一个宝贵的...

    Apache_Shiro_使用手册.docx

    Apache Shiro 是一个轻量级的 Java 安全框架,主要负责处理认证、授权、加密和会话管理等核心安全任务。它的设计简洁且易于使用,使得开发人员能够快速集成安全功能到各种类型的应用程序中。 Shiro 的核心组件包括 ...

    Apache Shiro 使用手册

    Shiro核心组件Aplication,Subject,SecurityManager, Realm, Authenticator, Authorizer. 介绍了Shiro认证,授权的实现及其机制原理。给了具体操作步骤及代码。

    Apache_Shiro_使用手册

    Apache Shiro 是一个轻量级的 Java 安全框架,主要负责处理认证、授权、加密和会话管理等核心安全任务。它旨在简化应用程序的安全实现,对比其他如 Spring Security 的框架,Shiro 更加易于理解和使用。 **认证过程...

    Apache_Shiro参考手册中文版

    Apache Shiro是一款功能丰富的开源安全框架,它为身份验证、授权、会话管理和加密提供了一套简洁直观的API,帮助开发者更容易地让应用程序实现安全功能。Shiro的设计目标是降低安全操作的复杂性,即使是复杂的概念也...

    Apache Shiro 使用手册(三) Shiro授权

    Apache Shiro 是一款强大的安全管理框架,它提供了身份验证(Authentication)、授权(Authorization)和会话管理(Session Management)等功能。本篇文章将详细讲解 Shiro 的授权机制,即如何控制用户在应用程序中...

    Apache-shiro使用手册

    ### Apache Shiro 使用手册知识点详解 #### 一、Shiro简介 - **定义**:Apache Shiro 是一款强大且易于使用的 Java 安全框架,它提供了包括认证、授权、密码加密和会话管理在内的多种安全服务功能。 - **特点**: ...

    Apache Shiro 使用手册(二) Shiro 认证

    一、Shiro认证过程 1、收集实体/凭据信息 代码如下://Example using most common scenario of username/password pair:UsernamePasswordToken token = new UsernamePasswordToken(username, password);//”...

    Apache Shiro 开发使用手册

    Apache Shiro 是一个轻量级且易于使用的 Java 安全框架,它专注于提供认证、授权、加密和会话管理功能,适用于多种类型的Java应用程序。Shiro 的设计目标是简化安全管理的实现,使得开发者能更专注于业务逻辑,而...

    ApacheShiro使用手册和Apache Shiro Reference Documentation

    ApacheShiro使用手册和Apache Shiro Reference Documentation 该文件下载了别人上传的两个文件,一个10分,一个30分,为了自己以后下载不花那么多分,也不让一些没有多少分的朋友能够下载,所以将别人资源下载后,将...

    apache-shiro-1.2.x-reference:《 Apache Shiro参考手册》(http

    apache-shiro-reference《Apache Shiro 参考手册》 Chinese translation of and the other article collection. The laset version of Apache Shiro is 1.5.x. You can also see the demos of the reference at ....

    Apache_Shiro&参考手册中文版&-converted.zip

    这个"Apache_Shiro参考手册中文版-converted.zip"文件包含了一个转换后的中文版Apache Shiro参考手册,方便中国开发者学习和理解Shiro的使用方法。 **一、认证(Authentication)** 在Shiro中,认证是指验证用户...

    Apache-Shiro-使用手册

    Apache-Shiro-使用手册 Apache Shiro 是一个框架,可用于身份验证和授权。本文提供了几个示例用来展示如何在 Java™ 应用程序中使用 Shiro 并给出了如何在一个 Grails web 应用程序中使用它的概述。

    Apache_Shiro_使用手册中文版

    Shiro使用授权器(Authorizer)组件来实现这一功能。 SessionManager为应用提供了一个统一的会话编程范式。Shiro的会话管理允许开发者在不同的应用架构层使用一致的会话API,不再受限于特定的容器,如Servlet或EJB...

Global site tag (gtag.js) - Google Analytics