全部設定
首先,我們建立了一個選民:
namespace BBIT\CoreBundle\Security\Authorization\Voter;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
class EventVoter implements VoterInterface
{
const VIEW = 'VIEW';
const EDIT = 'EDIT';
const DELETE = 'DELETE';
const CREATE = 'CREATE';
const LLIST = 'LIST';
public function supportsAttribute($attribute)
{
return in_array($attribute, array(
self::VIEW,
self::EDIT,
self::DELETE,
self::CREATE,
self::LLIST,
));
}
public function supportsClass($class)
{
$supportedClass = 'BBIT\CoreBundle\Entity\SomeEntity';
if (is_string($class)) {
if ($class === $supportedClass) {
return true;
} else {
return false;
}
}
return $supportedClass === get_class($class) || is_subclass_of(get_class($class), $supportedClass);
}
public function vote(TokenInterface $token, $entity, array $attributes)
{
$user = $token->getUser();
if (!is_object($user)) {
return VoterInterface::ACCESS_DENIED;
}
if (!$this->supportsClass($entity)) {
return VoterInterface::ACCESS_ABSTAIN;
}
$attribute = $attributes[0];
switch($attribute) {
case self::LLIST:
return VoterInterface::ACCESS_DENIED;
break;
case self::VIEW:
return VoterInterface::ACCESS_DENIED;
break;
case self::CREATE:
return VoterInterface::ACCESS_DENIED;
break;
case self::EDIT:
return VoterInterface::ACCESS_DENIED;
break;
case self::DELETE:
return VoterInterface::ACCESS_DENIED;
break;
}
return VoterInterface::ACCESS_DENIED;
}
}
這個選民與 symfony 文件中的預設選民略有不同,其另外的好處是能夠接受一個物件或類名本身作為引數。
其次,我們將建立一個 VoterSecurityhandler,它從 sonata 的 RoleSecurityHandler 擴充套件並覆蓋其中的一部分:
namespace BBIT\CoreBundle\Security\Handler;
use Sonata\AdminBundle\Admin\AdminInterface;
use Sonata\AdminBundle\Security\Handler\RoleSecurityHandler;
use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException;
class VoterSecurityHandler extends RoleSecurityHandler
{
/**
* {@inheritdoc}
*/
public function isGranted(AdminInterface $admin, $attributes, $object = null)
{
if (!is_array($attributes)) {
$attributes = array($attributes);
}
if ($object == $admin) {
$object = $admin->getClass();
}
foreach ($attributes as $pos => $attribute) {
$attributes[$pos] = $attribute;
}
try {
return $this->securityContext->isGranted($attributes, $object);
} catch (AuthenticationCredentialsNotFoundException $e) {
return false;
} catch (\Exception $e) {
throw $e;
}
}
/**
* {@inheritdoc}
*/
public function getBaseRole(AdminInterface $admin)
{
return '%s';
}
}
現在我們需要一個服務定義來將此處理程式定義為服務:
services:
...
sonata.admin.security.handler.voter:
class: BBIT\CoreBundle\Security\Handler\VoterSecurityHandler
arguments:
- @security.context
- [ROLE_SUPER_ADMIN]
現在我們可以告訴 sonata 使用我們的 VoterSecurityHandler:
sonata_admin:
...
security:
handler: sonata.admin.security.handler.voter
多數民眾贊成在這一點上,奏鳴曲將考慮你的選民,你應該好好去。