Zend ACL и доступ к конкретным объектам

Мне нужен ACL для моего прикладного уровня, и я искал Zend ACL, который, кажется, покрывает мои потребности, но меня смущает следующее [1]:

Например, если правило по умолчанию должно применяться к каждому зданию в городе, можно просто назначить правило городу, а не назначать одно и то же правило каждому зданию. Однако некоторые здания могут требовать исключения из такого правила, и это может быть достигнуто в Zend\Permissions\Acl\Acl назначая такие правила исключения для каждого здания, которое требует такого исключения.

Это замечательно. Именно то, что мне нужно. Тем не менее, как мне это сделать?

Прочитав документацию по Zend ACL, я не могу найти пример этого. Итак, допустим, у меня есть City а также Building ресурс и каждый реализует 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"?
   }

}

Поскольку комментарии в приведенном выше коде уже могут прояснить, что такое идентификатор ресурса? представляет ли он "тип" ресурса, т. е. это город или здание, или требуется уникальный идентификатор, т. е. "город-1" и т. д.?

Если ответ таков, что это должен быть "тип", тогда возникает вопрос; как указать уникальные здания? Однако, если ответ таков: идентификатор должен быть уникальным, тогда возникает вопрос; Как определить "тип" ресурса и "общее" разрешение каждого здания, как указано в цитате, взятой из документации.

Любое понимание будет высоко ценится.

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

1 ответ

Решение

resource Id должен быть уникальной ценностью. а для назначения глобальных правил вам необходимо использовать наследование ресурсов. просто нужно пройти city ресурс в качестве родителя для building ресурс при добавлении ресурсов в ACL.

вот образец:

$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 не знает и не заботится о том, какой у вас тип ресурса, если они имеют уникальные идентификаторы ресурсов, acl угрожает всем ресурсам как равным и ищет только resourceId и наследство.

когда вы определяете правила, вам нужно только предоставить resourceId для allow а также deny, не имеет значения, какого они типа, если они определены как ресурс и добавлены в стек ACL.

и когда ты делаешь $acl->inAllowed вам нужен только roleId а также resourceId и опять же, acl не заботится об их типе, только то, что они определены как ресурс abd, у которого есть родитель или нет...

Образец: я надеюсь, что это достаточно образец

$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
Другие вопросы по тегам