热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

phpcake文档,CakePHP中文手册

ACL访问控制Section1理解ACL是如何工作的大部分重要的资源都需要访问控制。ACL(Accesscontrollists)是一种细粒度,易维护和易管理的管理程

ACL 访问控制

Section 1 理解ACL是如何工作的

大部分重要的资源都需要访问控制。ACL(Access control lists)是一种细粒度,易维护和易管理的管理程序权限的方式。ACL主要处理两方面内容:一个是发起资源请求的对象,一个是希望获取的资源。用ACL的行话来说,请求使用资源的对象(通常是用户)称作请求访问对象,简称为ARO(access request object)。而希望获取的资源(通常为action和数据)被称作访问控制对象,简称为ACO(access control object)。我们将这些实体称之为'object'是因为有的时候发起请求的并不是用户本身,这种情况下你可以希望限制某些特定的controller的访问权限,而这些controller又不得不在应用程序的其他位置初始化逻辑。ACO可以是任何你希望进行访问控制的对象,从controller中的action到一个web服务接口,甚至是你祖母在线日记上的某一行。

一言以蔽之:ACL是用来定义一个ARO什么时候可以访问一个ACO。

为了帮助你更好的理解ACL,我们来看一个实际的例子。想象一下,我们的魔戒小队共同使用一台电脑。队长希望在最终决战之前保持任务的秘密和安全,具体的ARO如下:

Gandalf

Aragorn

Bilbo

Frodo

Gollum

Legolas

Gimli

Pippin

Merry

这些是系统中会发起访问请求的对象(ACO)。有一点需要说明:ACL 不是 一个用来验证用户合法性的系统。你应该已经有了保存用户信息和校验用户登录合法性的方法。当你知道了用户是谁后,ACL才开始发挥作用。好了,回到我们的双塔奇谋中。

我们的大法师甘道夫需要制作一张ACO的列表,确定有哪些需要控制的资源:

Weapons 武器

The One Ring 魔戒

Salted Pork 肉干

Diplomacy 外交协议

Ale 啤酒

传统情况下,我们会使用一种矩阵来管理这些,此矩阵展示了用户和与资源间相关对象的权限情况。如果此信息存储在一个表里,它可能会像下面这样,其中X表示拒绝访问,O代表允许访问:

Weapons The One Ring Salted Pork Diplomacy Ale

Gandalf X X O O O

Aragorn O X O O O

Bilbo X X X X O

Frodo X O X X O

Gollum X X O X X

Legolas O X O O O

Gimli O X O X X

Pippin X X X O O

Merry X X X X O

初看来,这个系统工作的非常好。这样的分配可以保证安全(只有Frodo可以碰魔戒),也可以防止一些意外(不让hobbits吃光所有的肉干)。看上去这个列表已经足够细致,并且简明易懂,但真的是这样吗?

对于一个小型系统,这样的矩阵列表可以完成任务。但是对于一个规模不断增长或者是拥有大量资源(ACO和ARO)的系统来说,这样一个表格将会变得非常笨重。比如我们试图控制上百个军营并且希望按组管理他们。矩阵的另一个缺点是你不能真正地按逻辑来将用户分组,并且按照逻辑分组对一组用户做出一连串的权限变更。比如,当战争一结束就能自动的允许Hobbit大快朵颐的享用肉干和啤酒,我们能很容易的改变一组用户的访问权限,为每一个用户创建独立的规则即乏味也不正确。

ACL是采用树状结构来实现的。通常ARO一棵树,ACO一棵树。使用树状结构来组织你的对象,权限仍然可以是细粒度的,而且同时可以对大局有很好的把握。最终成为白袍的甘道夫,当然明智的选择了使用ACL作为新的管理方式,结构如下:

Fellowship of the Ring:

Warriors

Aragorn

Legolas

Gimli

Wizards

Gandalf

Hobbits

Frodo

Bilbo

Merry

Pippin

Vistors

Gollum

按照这样的方式来组织我们的团队,我们可以定义这棵树的访问控制,并且应用这些权限到任意子节点上。默认的权限是禁止访问任何资源。

Fellowship of the Ring: [Deny: ALL]

Warriors [Allow: Weapons, Ale, Elven Rations, Salted Pork]

Aragorn

Legolas

Gimli

Wizards [Allow: Salted Pork, Diplomacy, Ale]

Gandalf

Hobbits [Allow: Ale]

Frodo

Bilbo

Merry

Pippin

Vistors [Allow: Salted Pork]

Gollum

如果我们希望知道Pippin是不是可以获得啤酒,我们首先要找出他在树种的路径,Fellowship->Hobbits->Pippin。我们会发现在3个节点拥有不同的属性,我们使用最明确的和Pippin,啤酒相关的权限。

Fellowship = DENY Ale, 禁止访问(因为默认情况时禁止访问任何资源)

Hobbits = ALLOW Ale, 允许访问

Pippin = ?; 没有明确定义,所以我们依然选择允许访问

最终结果:允许获得啤酒。

树结构也同样可以让我们非常方便的进行一些细粒度的调整,而且仍然具备了对ARO做出交替的变更:

Fellowship of the Ring: [Deny: ALL]

Warriors [Allow: Weapons, Ale, Elven Rations, Salted Pork]

Aragorn [Allow: Diplomacy]

Legolas

Gimli

Wizards [Allow: Salted Pork, Diplomacy, Ale]

Gandalf

Hobbits [Allow: Ale]

Frodo [Allow: Ring]

Bilbo

Merry [Deny: Ale]

Pippin [Allow: Diplomacy]

Vistors [Allow: Salted Pork]

Gollum

你可以看到,Aragorn比其他的战士多了使用外交协议的权限,这就是特别的微调。再说一下,默认的权限是禁止,并且只会在向下遍历树的时候被变更为允许。看一下Merry是不是可以获得啤酒,我们先查找她的路径:Fellowship->Hobbits->Merry 并查看对应的啤酒相关的权限:

Fellowship = DENY (默认禁止所有)

Hobbits = ALLOW: ale, 允许获得啤酒

Merry = DENY ale, 禁止获得啤酒

最终结果,禁止获得啤酒。

Section 2 定义权限:基于ini文件的ACL

Cake中第一种ACL实现是基于ini文件的。尽管ini文件非常有用并且稳定,我们仍然建议你使用基于数据库的ACL方案,因为这样就可以实时地创建新的ACO和ARO。即只在非常简单的小项目或者因为某些原因不能使用数据库的情况下使用这种ACL方案。

ARO/ACO 权限设定保存在/app/config/acl.ini.php文件中。在文件的最前面你可以找到使用方法:

; acl.ini.php - Cake ACL Configuration

; ---------------------------------------------------------------------

; Use this file to specify user permissions.

; aco = access control object (something in your application)

; aro = access request object (something requesting access)

;

; User records are added as follows:

;

; [uid]

; groups = group1, group2, group3

; allow = aco1, aco2, aco3

; deny = aco4, aco5, aco6

;

; Group records are added in a similar manner:

;

; [gid]

; allow = aco1, aco2, aco3

; deny = aco4, aco5, aco6

;

; The allow, deny, and groups sections are all optional.

; NOTE: groups names *cannot* ever be the same as usernames!

使用ini文件,你可以指定用户(ARO),用户所属的组和他们各自的权限。同样也可以设定组的权限。如何使用Cake ACL component来检查用户的权限,请参看11.4。

Section 3 定义权限:基于数据库的ACL

开始

默认的ACL方案是保存在数据库中的。dbACL由一组核心model和一个命令行脚本组成。Model用来和数据库交互以保存和获取ACL树。而命令行脚本可以帮助你创建数据库。

首先需要正确的配置你的数据库连接,具体请参考先前的章节。

然后使用Cake提供的命令行脚本来创建储存ACL的数据表,/cake/scripts/acl.php可以帮你完成这一系列操作。在命令行里/cake/scripts/目录下执行该命令:

$ php acl.php initdb

[TODO check in win env]

Initializing Database...

Creating access control objects table (acos)...

Creating access request objects table (acos)...

Creating relationships table (aros_acos)...

Done.

好了,你可以检查数据库看有没有新的表。如果你对Cake如何存储树状信息感到好奇,你可以研读一下修改过的数据库中树的遍历。基本上来说,它存储了节点以及它们在树中的位置。ACO和ARO分别在各自的树中保存这些节点,并且和model相对应。

现在你可以创建你的ARO ACO树了。

创建ARO和ACO

有两种方式来引用ARO或者ACO。一种是给它们一个ID,通常是他们对应的表的主键ID。另一种是给它们一个字符串别名。这两种方式并不是互斥的。

在Aro model中定义了创建新的ARO对象的方法:create()。该方法有3个参数:$link_id $parent_id $alias。此方法创建一个由$parent_id指定的父对象之下的ACL对象,如果传入的$parent_id为null,则作为一个根对象。$link_id允许你将当前用户对象链接到Cake的ACL结构。$alias参数允许你放入一个非整型ID的对象。

在你能够创建ACO和ARO之前,我们需要加载这些类。实现加载的最简单方法是使用$components数组,并将Cake ACL组件包含在Controller里:

var $components = array('Acl');

准备完毕,让我们看一个创建对象的例子,下列代码可以放置在一个action中:

$aro = new Aro();

// First, set up a few AROs.

// These objects will have no parent initially.

$aro->create( 1, null, 'Bob Marley' );

$aro->create( 2, null, 'Jimi Hendrix');

$aro->create( 3, null, 'George Washington');

$aro->create( 4, null, 'Abraham Lincoln');

// Now, we can make groups to organize these users:

// Notice that the IDs for these objects are 0, because

// they will never tie to users in our system

$aro->create(0, null, 'Presidents');

$aro->create(0, null, 'Artists');

//Now, hook AROs to their respective groups:

$aro->setParent('Presidents', 'George Washington');

$aro->setParent('Presidents', 'Abraham Lincoln');

$aro->setParent('Artists', 'Jimi Hendrix');

$aro->setParent('Artists', 'Bob Marley');

//In short, here is how to create an ARO:

$aro = new Aro();

$aro->create($user_id, $parent_id, $alias);

你也可以使用命令行方式创建ARO,$acl.php create aro

创建ACO的方式和ARO类似:

$aco = new Aco();

//Create some access control objects:

$aco->create(1, null, 'Electric Guitar');

$aco->create(2, null, 'United States Army');

$aco->create(3, null, 'Fans');

// I suppose we could create groups for these

// objects using setParent(), but we'll skip that

// for this particular example

//So, to create an ACO:

$aco = new Aco();

$aco->create($id, $parent, $alias);

对应的脚本命令为: $acl.php create aco

分配权限

创建好了ARO ACO,我们最后来为两者分配一下权限。这需要使用ACL component。让我们继续先前的例子:

// First, in a controller, we'll need access

// to Cake's ACL component:

class SomethingsController extends AppController

{

// You might want to place this in the AppController

// instead, but here works great too.

var $components = array('Acl');

// Remember: ACL will always deny something

// it doesn't have information on. If any

// checks were made on anything, it would

// be denied. Let's allow an ARO access to an ACO.

function someAction()

{

//ALLOW

// Here is how you grant an ARO full access to an ACO

$this->Acl->allow('Jimi Hendrix', 'Electric Guitar');

$this->Acl->allow('Bob Marley', 'Electric Guitar');

// We can also assign permissions to groups, remember?

$this->Acl->Allow('Presidents', 'United States Army');

// The allow() method has a third parameter, $action.

// You can specify partial access using this parameter.

// $action can be set to create, read, update or delete.

// If no action is specified, full access is assumed.

// Look, don't touch, gentlemen:

$this->Acl->allow('George Washington', 'Electric Guitar', 'read');

$this->Acl->allow('Abraham Lincoln', 'Electric Guitar', 'read');

//DENY

//Denies work in the same manner:

//When his term is up...

$this->Acl->deny('Abraham Lincoln', 'United States Army');

}

}

这个特别的controller并不是特别有用,主要是用来展示这个流程是怎么样的。在用户管理controller中使用ACL component会使最佳的场景。当创建了一个用户之后,他的ARO同时被创建并且放置在树中合适的位置,并且根据他的标识分配特定的ACO或者是ACO组。

可以使用与Cake一起打包的命令行脚本分配权限。此语法和model中的函数有些类似,而且可以通过执行$php acl.php帮助来查看它。

Section 4 校验权限:ACL Component

校验权限是ACL中最简单的部分了:只需要使用ACL Component中的check()函数就可以了。一个很好的实践就是在AppController中放置一个action来执行ACL权限校验。这样的好处是,可以在任何action中调用该方法来校验权限,我们看一下示例:

class AppController extends Controller

{

// Get our component

var $components = array('Acl');

function checkAccess($aco)

{

// Check access using the component:

$access = $this->Acl->check($this->Session->read('user_alias'), $aco, $action = "*");

//access denied

if ($access === false)

{

echo "access denied";

exit;

}

//access allowed

else

{

echo "access allowed";

exit;

}

}

}

基本上,通过在AppController基类里包含ACL component,从而使应用程序中的任何Controller中都可使用该方法。

$this->Acl->Check($aro, $aco, $action = '*');



推荐阅读
  • Django + Ansible 主机管理(有源码)
    本文给大家介绍如何利用DjangoAnsible进行Web项目管理。Django介绍一个可以使Web开发工作愉快并且高效的Web开发框架,能够以最小的代价构建和维护高 ... [详细]
  • Python已成为全球最受欢迎的编程语言之一,然而Python程序的安全运行存在一定的风险。本文介绍了Python程序安全运行需要满足的三个条件,即系统路径上的每个条目都处于安全的位置、"主脚本"所在的目录始终位于系统路径中、若python命令使用-c和-m选项,调用程序的目录也必须是安全的。同时,文章还提出了一些预防措施,如避免将下载文件夹作为当前工作目录、使用pip所在路径而不是直接使用python命令等。对于初学Python的读者来说,这些内容将有所帮助。 ... [详细]
  • t-io 2.0.0发布-法网天眼第一版的回顾和更新说明
    本文回顾了t-io 1.x版本的工程结构和性能数据,并介绍了t-io在码云上的成绩和用户反馈。同时,还提到了@openSeLi同学发布的t-io 30W长连接并发压力测试报告。最后,详细介绍了t-io 2.0.0版本的更新内容,包括更简洁的使用方式和内置的httpsession功能。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • MyBatis错题分析解析及注意事项
    本文对MyBatis的错题进行了分析和解析,同时介绍了使用MyBatis时需要注意的一些事项,如resultMap的使用、SqlSession和SqlSessionFactory的获取方式、动态SQL中的else元素和when元素的使用、resource属性和url属性的配置方式、typeAliases的使用方法等。同时还指出了在属性名与查询字段名不一致时需要使用resultMap进行结果映射,而不能使用resultType。 ... [详细]
  • 有没有一种方法可以在不继承UIAlertController的子类或不涉及UIAlertActions的情况下 ... [详细]
  • 在springmvc框架中,前台ajax调用方法,对图片批量下载,如何弹出提示保存位置选框?Controller方法 ... [详细]
  • 本文讨论了如何在codeigniter中识别来自angularjs的请求,并提供了两种方法的代码示例。作者尝试了$this->input->is_ajax_request()和自定义函数is_ajax(),但都没有成功。最后,作者展示了一个ajax请求的示例代码。 ... [详细]
  • Todayatworksomeonetriedtoconvincemethat:今天在工作中有人试图说服我:{$obj->getTableInfo()}isfine ... [详细]
  • Python操作MySQL(pymysql模块)详解及示例代码
    本文介绍了使用Python操作MySQL数据库的方法,详细讲解了pymysql模块的安装和连接MySQL数据库的步骤,并提供了示例代码。内容涵盖了创建表、插入数据、查询数据等操作,帮助读者快速掌握Python操作MySQL的技巧。 ... [详细]
  • ShiftLeft:将静态防护与运行时防护结合的持续性安全防护解决方案
    ShiftLeft公司是一家致力于将应用的静态防护和运行时防护与应用开发自动化工作流相结合以提升软件开发生命周期中的安全性的公司。传统的安全防护方式存在误报率高、人工成本高、耗时长等问题,而ShiftLeft提供的持续性安全防护解决方案能够解决这些问题。通过将下一代静态代码分析与应用开发自动化工作流中涉及的安全工具相结合,ShiftLeft帮助企业实现DevSecOps的安全部分,提供高效、准确的安全能力。 ... [详细]
  • SpringBoot简单日志配置
     在生产环境中,只打印error级别的错误,在测试环境中,可以调成debugapplication.properties文件##默认使用logbacklogging.level.r ... [详细]
  • 本文讨论了在ASP中创建RazorFunctions.cshtml文件时出现的问题,即ASP.global_asax不存在于命名空间ASP中。文章提供了解决该问题的代码示例,并详细解释了代码中涉及的关键概念,如HttpContext、Request和RouteData等。通过阅读本文,读者可以了解如何解决该问题并理解相关的ASP概念。 ... [详细]
  • 点击上方“新机器视觉”,选择加”星标”或“置顶”重磅干货,第一时间送达很早就想总结一下前段时间学习HALCON的心得,但由于其他的事情总是抽不出时间。去年有过一段时间的集中学习,做 ... [详细]
  • Iwanttointegratesort,order,maxandoffsetinafindAllquery.Thefollowingworksfine:我想在fin ... [详细]
author-avatar
moTzxx
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有