2019独角兽企业重金招聘Python工程师标准>>>

一、授权的三要素

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

权限
权限是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 标签
输出当前用户信息,通常为登录帐号信息

Xml代码
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验证成功,那么将认为授权成功,立即返回,结束认证。

转载于:https://my.oschina.net/kevin728971010/blog/783139

shiro 授权介绍相关推荐

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

    2019独角兽企业重金招聘Python工程师标准>>> 一.授权的三要素 授权有着三个核心元素:权限.角色和用户. 权限 权限是Apache Shiro安全机制最核心的元素.它在应用 ...

  2. shiro框架---shiro配置介绍(一)

    接上一篇文章shiro框架-通过系统介绍shiro框架中的实现逻辑   项目已分享到GitHub上,如果需要的可以看下,springboot+shiro项目Git下载地址. shiro在springb ...

  3. 使用Redis缓存Shiro授权认证信息,搭建集群权限系统

    应用如果做负载均衡,集群间session需要共享,如果session没有共享,用户登录系统以后session保存在登录的应用里面,其他应用里面没有session,没有登陆状态,访问会失败.下面介绍一个 ...

  4. shiro教程(3)-shiro授权

    1 shiro授权 1.1 授权流程 1.2 授权方式 Shiro 支持三种方式的授权: 1.编程式:通过写if/else 授权代码块完成: Subject subject = SecurityUti ...

  5. Shiro框架:授权流程、授权方式、Shiro授权入门程序、自定义Realm进行授权

    一.Shiro授权: 1.授权与权限: (1)授权:访问控制,必须具有该资源的访问权限才可以访问该资源. (2)权限模型:标准权限数据模型包括 :用户.角色.权限(包括资源和权限).用户角色关系.角色 ...

  6. Shiro授权流程图

    Shiro授权流程 Shiro授权流程图 Shiro授权流程图 根据Shiro授权流程,绘制流程图如下:

  7. 分布式平台下的HS(High-Security) --Shiro 授权

    授 权 授权实质上就是访问控制 - 控制用户能够访问应用中的哪些内容,比如资源.Web页面等等.多数用户执行访问控制是通过使用诸如角色和权限这类概念完成的.也就是说,通常用户允许或不允许做的事情是根据 ...

  8. Day374.shiro授权Shiro+jsp整合Springboot -Shiro

    Shiro授权 一.授权 授权,即访问控制,控制谁能访问哪些资源.主体进行身份认证后需要分配权限方可访问系统的资源,对于某些资源没有权限是无法访问的. 二.关键对象 授权可简单理解为who对what( ...

  9. [J2EE][shiro][授权和认证框架]

    1.原文地址 http://www.lgygg.wang/lgyblog/2019/09/04/j2eeshiro%e6%8e%88%e6%9d%83%e5%92%8c%e8%ae%a4%e8%af% ...

最新文章

  1. TensorFlow用法
  2. webService——学习(3):使用JDK开发webService
  3. .h 与.hpp文件的区别
  4. if/ else 你真的会吗?
  5. MFC中CString和int的转换
  6. 解决:elasticsearch 更新报错:The number of object passed must be even but was [1]
  7. 脉冲宽度调制pdm_STM32第七章-脉冲宽度调制
  8. 【Java】带你走进Debug的世界
  9. 点云nurbs曲面重建c++代码_【科普】抢先收藏!点云数据处理技术概要
  10. Python 中的全局变量
  11. python图合并_Python-numpy实现灰度图像的分块和合并方式
  12. bootstrap 固定最底部_防腐木立柱怎么固定
  13. mysql存储过程中like用法
  14. bgp状态idle什么原因_27-高级路由:BGP状态
  15. c语言设计一个自动阅卷功能,程序阅卷论文,关于编程题自动阅卷系统的设计实现相关参考文献资料-免费论文范文...
  16. 用HTML制作个人简历
  17. 故障处理 软件 需求_高线轧机轴承振动在线监测与故障诊断分析
  18. 统计遗传学:第二章,统计分析概念
  19. 农林牧渔行业S2B2C系统网站提升品牌知名度,提升盈利水平
  20. win10 官方纯净版安装详细图解

热门文章

  1. 微信如何实现自动跳转到用其他浏览器打开指定页面下载APP
  2. 关于zipfile解压出现的字符编码问题
  3. Web Bundler CheatSheet, 选择合适的构建打包工具
  4. 如何在 Linux 中创建一个共享目录
  5. Microsoft.Data.ConnectionUI.DataConnectionDialog
  6. 分享一个 org.w3c.dom XML 封装
  7. JavaScript 读书笔记(二)— Date类型
  8. 使用Apache Commons Configuration读取配置信息
  9. [你必须知道的css系列]第一回:丰富的利器2:CSS选择符之子选择符、相邻选择符...
  10. 久在樊笼里,复得返自然