重用@Security批注

时间:2015-11-10 10:14:35

标签: php security symfony

@Security注释定义的权限时,是否可以检查用户是否可以从控制器外部访问控制器?
例如:
如果我们有这样的控制器:

/**
* @Security("has_role('ROLE_ADMIN')")
*/
function myController() { ... }

我们可以执行这样的授权检查:

[伪代码]

    // get an object representation of `@Security` annotation
    $controllerSecurity = $this->get('some_magic_service')
        ->getSecurityForController('Bundle:Controller:myController');
   // check if a current user is granted
   if ($controllerSecurity->isGranted($user)) { ... }

[/伪]

我认为Symfony核心安全组件在检查控制器授权时会做类似的事情......

2 个答案:

答案 0 :(得分:2)

不要试图检查每个路由/控制器的访问权限,只是不要为那些无权访问的人显示您的菜单项。创建一个返回用户类型的服务类。

services.yml

app_security.access.manager:
    class: AppBundle\Services\SecurityAccessManager
    arguments: [@security.authorization_checker,@security.token_storage]

SecurityAccessManager.php

<?php


namespace AppBundle\Services;


use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;

class SecurityAccessManager
{
    private $authorizationChecker;
    private $tokenStorage;   

    public function __construct(AuthorizationChecker $authorizationChecker,TokenStorage $tokenStorage)
    {
        $this->authorizationChecker = $authorizationChecker;
        $this->tokenStorage = $tokenStorage;

    }


    public function getUser()
    {
        return $this->tokenStorage->getToken()->getUser();
    }


    public function isAdmin()
    {
        if($this->authorizationChecker->isGranted('ROLE_ADMIN') !== true) {
            return false;
        } else {
            return true;
        }
    }  

}

然后在菜单构建器中,您需要注入类并检查权限:

这是KNP菜单的一个例子:

app.menu.builder
        class: AppBundle\Menu\MenuBuilder
        arguments: [@knp_menu.factory,@medapp_security.access.manager]

和menubuilder

class MenuBuilder extends ContainerAware
{
    /**
     * @var FactoryInterface
     */
    private $factoryInterface; 
    private $securityAccessManager;

   public function __construct(FactoryInterface $factoryInterface, SecurityAccessManager $securityAccessManager)
    {  
        $this->factoryInterface = $factoryInterface;   
        $this->securityAccessManager = $securityAccessManager;

    }

...

$menu->addChild('user link',..);
if ($this->securityAccessManager->isAdmin())     $menu->addChild('admin link',..);

答案 1 :(得分:0)

isGranted()被调用时,它只使用三个标准Symfony2选民(+自定义选民,如果你已定义它): AuthenticatedVoter ExpressionVoter < / strong>和 RoleHierarchyVoter

AuthenticatedVoter只检查当前令牌身份验证级别: IS_AUTHENTICATED_FULLY IS_AUTHENTICATED_REMEMBERED IS_AUTHENTICATED_ANONYMOUSLY

因此,如果您不使用角色,则默认情况下只有AuthenticatedVoter会返回结果。

如果要为控制器的任何操作定义自定义权限,可以使用Voters。我认为它最适合你的任务。

然后你可以在这样的任何动作的顶部调用选民:

public function indexAction()
{
    $this->denyAccessUnlessGranted('permission', $entity);
    // your code
}

但是,如果您要对应用的整个部分应用安全限制,可以使用access_control