Zend ACL和访问特定对象

时间:2014-09-07 04:19:03

标签: php zend-framework2 zend-acl

我的应用程序层需要一个ACL,我一直在研究Zend ACL,这似乎可以满足我的需求,但我对以下[1]感到困惑:

  

例如,如果要将默认规则应用于a中的每个建筑物   城市,人们只会将规则分配给城市,而不是   为每个建筑物分配相同的规则。有些建筑可能需要   但是,这种规则的例外情况可以通过以下方式实现   Zend\Permissions\Acl\Acl通过为每个规则分配此类例外规则   建筑需要这样的例外。

这很棒。正是我需要的。但是,我该如何做到这一点?

从阅读Zend ACL的文档,我实际上找不到这样的例子。所以,假设我有CityBuilding资源,每个都实现了ResourceInterface。像这样:

class City implements ResourceInterface {

   public function getResourceId()
   {
      return "city"; // Is this supposed to be the "type" or the "unique Id"?
   }

   public $buildings = array();

}

class Building implements ResourceInterface {

   public function getResourceId()
   {
      return "building"; // Again, the "type" or "unique Id"?
   }

}

由于上面代码中的注释可能已经明确,资源ID是什么?它是否代表资源的“类型”,即这是一个城市或建筑物,还是需要一个唯一的Id,即“城市-1”等?

如果答案是它需要是“类型”那么问题就变成了;如何指定独特的建筑物?但是,如果答案是Id必须是唯一的,那么问题就变成了;如何识别资源的“类型”和每个建筑物的“一揽子”权限,如文档中引用的那样。

非常感谢任何见解。

[1] http://zf2.readthedocs.org/en/latest/modules/zend.permissions.acl.intro.html

1 个答案:

答案 0 :(得分:2)

resource Id需要是唯一值。并且为了分配全局规则,您需要为资源使用继承。很简单,当您向acl添加资源时,需要将city资源作为building资源的父资源传递。

这是一个示例:

$acl = new Acl();

//the original Acl resource class takes a `resourceId` as constructor parameter
$mycity1 = new Resource('mycity1');
$acl->addResource($mycity1);

$mybuiding1 = new Resource('mybulding1');
//city is the buildings parent
$acl->addResource($mybuiding1,$mycity1);

//you dont even have to create a class just define the resource as string
$acl->addResource('secure_buildings',$mycity1);

$acl->addRole('myrole1');
//roles have inheritance too
$acl->addRole('myrole2','myrole1');

//myrole1 and myrole2 has access to city and all its building
$acl->allow('myrole1','mycity1');
//myrole2 has access to city and all its building except 'secure_buildings'
$acl->deny('myrole2','secure_buildings');

子资源bulding从父city继承规则(如果没有为其定义)。

更新评论:

ACL不知道并且不关心您拥有什么资源类型,只要它们具有唯一的资源ID,acl威胁所有资源相同并且仅查找resourceId和继承。

当您定义规则时,您只需要为resourceIdallow提供deny,只要将它们定义为a $acl->inAllowed,它们的类型无关紧要资源并添加到ACL的堆栈中。

当你执行roleId时,你只需要一个resourceId$acl = new Acl(); $acl->addResource('City'); //all the cities $acl->addResource('myCity1', 'City'); //city1 inherits City $acl->addResource('Building', 'City'); //all the buildings in all the cities $acl->addResource('normal_buildings', 'Building'); $acl->addResource('secure_buildings', 'Building'); $acl->addResource('top_secure_buildings', 'secure_buildings'); $acl->addRole('Civilian'); $acl->addRole('High_Level_Security', 'Civilian'); $acl->allow('Civilian', 'City'); $acl->deny('Civilian', 'secure_buildings'); $acl->allow('High_Level_Security', 'secure_buildings'); $acl->deny('High_Level_Security', 'top_secure_buildings'); var_dump($acl->isAllowed('Civilian', 'City'));//true -> direct allow rule var_dump($acl->isAllowed('Civilian', 'myCity1'));//true -> inherited from City allow rule var_dump($acl->isAllowed('Civilian', 'Building'));//true -> inherited from City allow rule var_dump($acl->isAllowed('Civilian', 'normal_buildings'));//true -> inherited from City allow rule var_dump($acl->isAllowed('Civilian', 'secure_buildings'));//false -> direct deny rule var_dump($acl->isAllowed('Civilian', 'top_secure_buildings'));//false -> inherited from secure_building deny rule var_dump($acl->isAllowed('High_Level_Security', 'City'));//true -> inherited from Civilian->City allow rule var_dump($acl->isAllowed('High_Level_Security', 'myCity1'));//true -> inherited from Civilian->City allow rule var_dump($acl->isAllowed('High_Level_Security', 'Building'));//true -> inherited from Civilian->City allow rule var_dump($acl->isAllowed('High_Level_Security', 'normal_buildings'));//true -> inherited from Civilian->City allow rule var_dump($acl->isAllowed('High_Level_Security', 'secure_buildings'));//true -> direct allow rule var_dump($acl->isAllowed('High_Level_Security', 'top_secure_buildings'));//false -> direct deny rule ,并且acl不再关心他们的类型,只是他们被定义为资源abd他们是否有父母......

示例:我希望这是足够的样本

{{1}}