本篇是对Shiro体系架构的介绍,本栏目大部分内容来自于Shiro官网。翻译过程中已经尽量保证用词的准确性和易懂性,如有不准确或者不确切的地方,请联系作者加以修改。本篇内容翻译自Authorization特征与Authorization官方指南。

Authorization,也称为访问控制,是确定对应用程序中资源的访问权限的过程。换句话说,确定“谁有权访问什么”。授权用于解决安全性问题,例如“是否允许用户编辑帐户”,“是否允许该用户查看此网页”,“此用户是否有权访问此按钮“等,授权是任何应用程序的关键要素,但它有时候会非常复杂,Shiro的目标是消除授权方面的许多复杂性,以便您可以更轻松地构建安全软件。面我们先介绍一下Authentication中会遇到的术语和Authorization的特征:

Authorization术语:

  • users:用户,用户实质上是与应用程序有关的主体,正如前面讨论的Subject实例是Shiro中的用户的概念,它不一定是指一个人一般的用户,也可能是第三方应用等。用户的权限是通过角色(roles)和权限(permission)关联使可以在程序中执行某些操作。
  • roles:角色,角色实际上是权限的集合,用于简化权限和用户的管理。因此,可以为用户分配角色,而不是直接为他们分配权限,这会因更大的用户群和更复杂的应用程序而变得复杂。因此,例如,银行应用程序可能具有管理员角色或银行出纳员角色。Shiro支持显式角色和隐式角色两种角色。
  1. 隐式角色,隐式角色是指您的应用程序暗含了一组权限,因为用户具有特定角色,而不是为角色明确分配权限或您的应用程序检查这些权限。代码中的角色检查通常反映了隐式角色。您可以查看患者数据,因为您具有管理员角色。您可以创建帐户,因为您具有银行出纳员角色。这些名称存在的事实与软件的实际功能无关。大多数人都以这种方式使用角色。这是最简单的方法,但是除了最简单的应用程序之外,它可能为其他所有程序带来很多维护和管理问题。
  2. 显式角色,显式角色具有显式分配的权限,因此是显式的权限集合。代码中的权限检查反映了显式角色。您可以查看患者数据,因为您具有查看角色数据权限,这是管理员角色的一部分。您可以创建帐户,因为您在银行出纳员角色中拥有创建帐户权限。您可以执行这些操作,不是因为有一些基于字符串的隐式角色名称,而是因为相应的权限已显式分配给您的角色。显式角色的最大好处是易于管理,并减少了应用程序维护。如果您需要添加,删除或更改角色,则无需触摸源代码即可完成。在Shiro中,您还可以在运行时动态添加,删除或更改角色,并且您的授权检查将始终具有最新值。这意味着您不必强迫用户注销并重新登录即可获取其新权限。
  • permission :权限,权限是安全策略的最基本的级别,它们是功能的声明。权限代表可以在您的应用程序中执行的操作。格式正确的权限描述了资源类型以及与这些资源进行交互时可以执行的操作。你可以打开一个?你能一个文件?你可以删除一个客户记录?你能一个按钮吗?数据相关资源的常见操作是创建,读取,更新和删除,通常称为CRUD。
  • permission granularity :权限粒度,在Shiro中,您可以定义任意深度的权限。以下是一些按粒度顺序排列的常见权限级别。
  1. 资源级别-这是最广泛,最容易构建的资源。用户可以编辑客户记录或打开门。指定了资源,但未指定该资源的特定实例。
  2. 实例级别-权限指定资源的实例。用户可以编辑IBM的客户记录或打开厨房门。
  3. 属性级别-权限现在指定实例或资源的属性。用户可以编辑IBM客户记录上的地址。

Authorization特征:

  • 基于Subject: 在Shiro中, 几乎所有的操作都基于被称为Subject的当前正在执行的用户.而且你可以访问该subject对象去检索Subject并且可以在代码中的任何位置检查其角色、权限挥着其他相关属性。这使您在应用程序中更容易理解和使用Shiro。
  • 基于roles和permissions的权限检查:因为不同应用之间授权的复杂性是不同的,Shiro一开始就被设计为灵活的同时支持基于role和permission的权限控制,你可以根据你的项目需要来选择。
  • 强大易用的权限语法:作为一个选项,Shiro提供了一种开箱即用的权限语法,称为通配符权限,帮助您对应用程序可能具有的细粒度访问策略进行建模。通过使用Shiro的通配符权限,可以获得易于处理和可读的语法。
  • 多种执行选项:Shiro中的授权检查可以通过代码内检查、JDK 1.5注解、AOP和JSP/GSP标记库来完成。Shiro的目标是根据您的喜好和项目需求,让您选择使用您认为最好的选项。
  • 强大的缓存支持:任何现代的开源的企业缓存产品都可以插入Shiro,以提供快速高效的用户体验。对于授权,缓存对于在较大的应用程序中或使用后端安全数据源的更复杂策略中的性能至关重要
  • 支持数据源插件:Shiro使用可插入的数据访问对象(称为Realms)连接到安全数据源,在那里保存访问控制信息,如LDAP服务器或关系数据库。为了帮助您避免自己构建和维护集成,Shiro为流行的数据源(如LDAP、Active Directory和JDBC)提供了开箱即用Realm。如果需要,您还可以创建自己的Realm来支持基本领域中未包含的特定功能。
  • 支持任何数据模型:Shiro可以支持任何数据模型的访问控制,它不会强迫您使用单一模型。您的realm实现最终决定了您的权限和角色是如何组合在一起的,以及是否向Shiro返回“yes”或“no”答案。这个特性允许您以您选择的方式设计您的应用程序。

Authorization的使用:

前面我们介绍了Authorization中的一些术语和特征,那么我们该如何在应用程序中使用Shiro进行授权管理呢?Shiro支持三种模式进行授权管理。

1.以编程的模式在代码中进行控制。在用户进行身份验证成功之后,我们可以通过SecurityUtils获取当前Subject的实例,该实例提供了很多方法进行权限管理与权限验证,代码如下:

//是否有该角色
Subject currentUser = SecurityUtils.getSubject();
if (currentUser.hasRole("administrator")) {
} else {
}
//是否允许该权限操作
Permission printPermission = new PrinterPermission("laserjet3000n","print");
If (currentUser.isPermitted(printPermission)) {
} else {
}
//是否允许该权限操作
String perm = "printer:print:laserjet4400n";
if(currentUser.isPermitted(perm)){
} else {
}

2.以注解的模式,如下代码所示:

//该方法需要拥有account:create权限才能调用
@RequiresPermissions("account:create")‏
public void openAccount( Account acct ) {//create the account
}
//该方法需要拥有teller角色才能调用
@RequiresRoles( "teller" )
public void openAccount( Account acct ) {//do something in here that only a teller//should do
}

3.以JSP 标签的方式控制,在web应用中,Shiro提供了一个标签库,我们可以使用JSP标签的形式进行权限管理。示例代码如下

<%@ taglib prefix="shiro" uri=http://shiro.apache.org/tags %>
<html>
<body><shiro:hasPermission name="users:manage"><a href="manageUsers.jsp">Click here to manage users</a></shiro:hasPermission><shiro:lacksPermission name="users:manage">No user management for you!</shiro:lacksPermission>
</body>
</html>

Authorization权限控制流程:

我们现在已经知道授权是基于当前Subject对象的,接下来我们看一下当授权被调用时Shiro内部发生了什么。如下图为Shiro的体系结构图,只保留了与授权相关的组件。每个数字代表授权操作过程中的一个步骤:

1.应用程序或框架代码调用当前Subject实例的 hasRole*,checkRole*,isPermitted*,或checkPermission*方法变体,传递的参数为角色或者具体权限值.

2.该Subject实例,一般是是DelegatingSubject(或子类)委托给应用程序的SecurityManager调用与Subject实例几乎相同的securityManager的hasRole*,checkRole*,isPermitted*,或checkPermission*方法变体(所述securityManager实现了org.apache.shiro.authz.Authorizer接口,它定义了所有特定Subject的授权方法)。

3.SecurityManager是一个基础的综合型组件,通过调用authorizer各自的hasRole*, checkRole*, isPermitted*和checkPermission*方法转发或者委托给它内部的org.apache.shiro.authz.Authorizer实例,authorizer默认的实现为ModularRealmAuthorizer实例。它在授权操作时支持一个或者多个Realms组合。

4.每一个配置的Realm都会被检测是否实现了相同的Authorizer接口,如果实现该接口将会调用
该Realm自己的hasRole*, checkRole*, isPermitted*或者checkPermission*方法

如下为测试代码,与shiro.ini配置中的内容,关于shiro.ini中权限角色的配置后面会详细讲解。

private static void hasRole(Subject subject) {//权限检查 是否拥有指定角色boolean hasRole = subject.hasRole("role1");System.out.println("hasRole role1 " + hasRole);//是否拥有指定角色,传参为List 返回为数组boolean [] hasRoles = subject.hasRoles(Arrays.asList(new String[]{"role1", "role2", "role3"}));System.out.println("hasRole role1 " + hasRoles[0] + " role2 " + hasRoles[1] + " role2 " + hasRoles[2]);//是否拥有指定的所有角色,只有角色同时被拥有才返回true 否则返回falseboolean  hasAllRoles = subject.hasAllRoles(Arrays.asList(new String[]{"role1",  "role2"}));System.out.println("hasAllRoles role1,role2 " + hasAllRoles);}private static void checkRole(Subject subject){try{subject.checkRole("role1");System.out.println("验证角色 role1成功");}catch (AuthorizationException e) {System.out.println("验证角色 role1失败");}try{subject.checkRoles("role1", "role2");System.out.println("验证角色 role1, role2成功");}catch (AuthorizationException e) {System.out.println("验证角色 role1, role2失败");}try{subject.checkRoles(Arrays.asList(new String[]{"role1", "role2", "role3"}));System.out.println("验证角色 role1, role2, role3成功");}catch (AuthorizationException e) {System.out.println("验证角色 role1, role2, role3失败");}
}
private static void isPermitted(Subject subject) {//是否有指定权限boolean isPermitted = subject.isPermitted("user:add");System.out.println(isPermitted);//是否有指定的权限,拥有所有权限时,返回true,否则返回falseboolean isPermittedAll = subject.isPermittedAll("user:add","user:update");System.out.println(isPermittedAll);//是否拥有指定权限,返回对应的布尔值数组,有则返回ture,没有返回falseboolean isPermitteds[] =subject.isPermitted("user:add","user:update");System.out.println("user:add " + isPermitteds[0] + " user:update " + isPermitteds[1]);
}private static void checkPermitted(Subject subject) {//是否有指定权限try{subject.checkPermission("user:add");System.out.println("有权限 可以执行 user:add操作");}catch (AuthorizationException e) {System.out.println("无权限不 可以执行 user:add操作");}try{subject.checkPermissions("user:add", "user:update");System.out.println("有权限 可以执行 user:add user:update操作");}catch (AuthorizationException e) {System.out.println("无权限不 可以执行 user:add user:update操作");}
}
[users]
pharos = 123456, role1, role3[roles]
role1 = user:add
role2 = user:add, user:update
role3 = user:delete

Authorization—权限控制流程相关推荐

  1. android p 权限流程,Android native 权限控制流程

    关联文章: 前言: 在 Android Runtime Permission 详解 中详细的说明了permission 在Android 6.0 前后的区别,对于M 以后应用可以通过checkPerm ...

  2. authorization权限控制_Nacos 权限控制介绍及实战

    方案背景 Nacos自开源依赖,权限控制一直需求比较强烈,这也反应了用户需求将Nacos部署到生产环境的需求.最新发布的Nacos 1.2.0版本已经支持了服务发现和配置管理的权限控制,保障用户安全上 ...

  3. EasyBuy项目SpringSecurity权限控制流程笔记

    1.搭建两个子模块(admin_service,admin_service_web) 2.在父项目的pom.xml中添加security的依赖 <dependency><groupI ...

  4. authorization权限控制_MVC中AuthorizeAttribute用法并实现权限控制

    1.创建一个类(用来检查用户是否登录和用户权限)代码如下: public class AuthorizeFilterAttribute: AuthorizeAttribute { //Authoriz ...

  5. authorization权限控制_授权(Authorization)

    授权 授权是指验证用户是否允许做某件事的过程.Yii提供两种授权方法: 存取控制过滤器(ACF)和基于角色的存取控制(RBAC). 存取控制过滤器 存取控制过滤器(ACF)是一种通过 yii\filt ...

  6. shiro 方法级别细粒度权限控制_Shiro的认证和权限控制

    从类别上分,有两大类: - 认证:你是谁?–识别用户身份. - 授权:你能做什么?–限制用户使用的功能. 权限的控制级别 从控制级别(模型)上分: - URL级别-粗粒度 - 方法级别-细粒度 - 页 ...

  7. vue实现角色权限控制

    一.前言 在广告机项目中,角色的权限管理是卡了挺久的一个难点.首先我们确定的权限控制分为两大部分,其中根据粒的大小分的更细: 接口访问的权限控制 页面的权限控制 菜单中的页面是否能被访问 页面中的按钮 ...

  8. web业务系统权限控制

    来源:http://blog.chinaunix.net/u1/52224/showart_410119.html 在以往的系统设计中,要么缺乏权限控制,要么就是权限控制很简单,,要么权限控制功能虽然 ...

  9. OAuth2.0 原理流程及其单点登录和权限控制

    作者:王克锋 kefeng.wang/2018/04/06/oauth2-sso 单点登录是多域名企业站点流行的登录方式.本文以现实生活场景辅助理解,力争彻底理清 OAuth2.0 实现单点登录的原理 ...

最新文章

  1. CKFinder 自定义文件路径扩展ConfigurationPathBuilder
  2. C++对象模型6——g++中虚继承的实现
  3. MxGraph从入门到精通之1:运行HelloWorld示例程序
  4. Android中Dialog与DialogFragment的对比
  5. 解决Weblogic 本机可以访问控制台,网络IP访问不了
  6. python中pandas安装视频教程_详解Python中pandas的安装操作说明(傻瓜版)
  7. 课时105.边框属性下(掌握)
  8. ASP.NET 数据库缓存依赖
  9. Tomcat10 下载和配置 Linux 环境
  10. Chapter 2 Build Caffe
  11. Indented Inventory BOM如何转为最终的单层采购BOM
  12. Tenth season fifth episode,Rachel‘s sister came again???????
  13. N186_五险一金按名字和身份证汇聚(单表)
  14. html p标签的补白,padding css内补白padding教程
  15. 爬取腾讯视频网站数据
  16. NFT跟元宇宙有什么关系?
  17. 献给父亲,《手风琴》;《夺命手术》,母爱无疆。
  18. 字符串?=字符+\0
  19. liunx 系统 一键安装
  20. 我有一个计算机梦想作文500,我的梦想作文500字

热门文章

  1. 顶尖文案app_为了让你多读点书,这个APP请来了这些世界顶级“文案”
  2. java百万级大数据量导出
  3. Neural Baby Talk学习笔记
  4. cv.waitkey()参数详解
  5. 单片机实验(十五)74LS47数码管译码
  6. context.getContentResolver().query()详细用法详解
  7. Product-based Neural Networks (PNN) - 改进特征交叉的方式
  8. 常用符号计算机输入法,玩电脑必备:一些特殊符号的组合输入法
  9. 正则校验必须由数字 字母 和 特殊符号组成的正则
  10. 移动WEB各种布局开发笔记