Symfony 2:获取控制器之外的安全上下文

The*_*lis 4 php symfony

我正在尝试编写一个需要访问用户权限级别的事件监听器.在控制器中,我使用以下代码

码:

$securityContext = $this->container->get('security.context');

if($securityContext->isGranted('ROLE_USER')){
    //Do Something
}
Run Code Online (Sandbox Code Playgroud)

但是在控制器之外我无法弄清楚如何获得安全上下文.可能吗?

Ram*_*iss 20

最好的方法是使用(如phpisuber所说)通过服务容器注入依赖项.但是,不应该注入整个容器(这被认为是不好的做法,因为它会使你的整个类不那么可测试并且打破松耦合),你应该像这样注入服务:security.context

acme_foo.bar_service:
    class: %acme_foo.bar_service.class%
    arguments:
        - @security.context
Run Code Online (Sandbox Code Playgroud)

您的服务可能是这样的:

<?php
namespace Acme\FooBundle\Service;

use Symfony\Component\Security\Core\SecurityContext;

class BarService
{
    /**
     * @var SecurityContext
     */
    protected $context;

    /**
     * @param SecurityContext $context
     */
    public function __construct($context)
    {
        $this->context = $context;
    }

    public function doSomething()
    {
        return $this->context->isGranted('ROLE_USER');
    }
}
Run Code Online (Sandbox Code Playgroud)


php*_*r01 5

有两种方法可以将其置于控制器之外:

依赖注入:

这是正确的方法,您只需要在此处的文档中.

mybundle.model.mymodel:
class: %mybundle.model.myclass%
arguments: [@servicecontainer]
Run Code Online (Sandbox Code Playgroud)

快速和肮脏:

global $kernel;
$securityContext = $kernel->getContainer()->get('security.context');
Run Code Online (Sandbox Code Playgroud)

  • 请不要使用快速而肮脏的解决方案!你永远不应该使用全球! (3认同)
  • @ phpisuber01这是*最少知识的原则*.当您将整个服务容器作为依赖项注入时,您的对象就在于它真正需要的东西.如果不构建整个容器,您的设备将难以测试.[本视频](http://www.youtube.com/watch?v=RlfLCWKxHJ0)可以帮助您理解这一原则 (3认同)
  • @Touki关心解释更多?我真的很感兴趣.RamonKleiss是正确的Q&D解决方案使用不是一个好主意,但我把它包括在那些想要进行快速概念检查的人之前,通过symfony配置花费20分钟的facedesking将容器注入模型.测试您的代码,然后返回并正确注入容器.Mmmhm. (2认同)