不推荐使用Symfony 2 SecurityContext类

时间:2015-04-13 13:15:03

标签: security symfony

当我尝试在symfony demo

上访问app / example时出现以下错误
  

错误:Symfony \ Component \ Security \ Core \ SecurityContext类是   自2.6版以来已弃用,将在3.0中删除。使用   Symfony的\分量\安全\核心\认证\令牌\存储\ TokenStorage   或Symfony \ Component \ Security \ Core \ Authorization \ AuthorizationChecker   代替。

服务器正在使用200状态代码返回正确答案。

我在Google上没有发现任何相关信息。有没有人在遇到此错误之前和/或知道如何修复它?

3 个答案:

答案 0 :(得分:46)

<强>解释

从Symfony 2.6开始,SecurityContext被分为TokenStorageAuthorizationChecker(请参阅:Symfony Blog - "New in Symfony 2.6: Security component improvements")。

这样做的主要原因是为了防止在将SecurityContext注入您自己的服务时经常发生的循环引用。

<强>解决方案

更改本身是100%向后兼容的(如链接博客文章中所述),您只需要重写访问SecurityContext的方式。

// Symfony 2.5
$user = $this->get('security.context')->getToken()->getUser();
// Symfony 2.6
$user = $this->get('security.token_storage')->getToken()->getUser();

// Symfony 2.5
if (false === $this->get('security.context')->isGranted('ROLE_ADMIN')) { ... }
// Symfony 2.6
if (false === $this->get('security.authorization_checker')->isGranted('ROLE_ADMIN')) { ... }

您可以通过在源代码(包括供应商目录)中对security.contextSecurityContext进行文本搜索来尝试查找罪魁祸首。

但正如你所说,你使用的是vanilla Symfony 2.6,它似乎只是使用了一些很快被弃用的方法。所以你可能只是使用这个......

解决方法

由于Symfony通过触发E_USER_DEPRECATED错误进行了弃用,您只需在启动Symfony AppKernel时禁用它们:

// app/AppKernel.php
class AppKernel extends Kernel
{
    public function __construct($environment, $debug) {
        // Keep error reporting like it was and disable only deprecation warnings.
        error_reporting(error_reporting() & (-1 ^ E_DEPRECATED));
        // ...
    }
}

我个人喜欢弃用警告,因为Symfony的更改日志倾向于提供有关如何更改代码以支持Symfony的未来版本的非常详细的信息,并且通常在方法实际发生前几个月触发了弃用警告弃用。

答案 1 :(得分:1)

这不是一个正确的错误,只是一个警告。

不推荐使用的类是计划在将来的版本中删除的类(在本例中为Symfony)。

它建议您停止使用它,并指向较新的(和替代)类TokenStorageAuthorizationChecker,这将完成相同的任务。

答案 2 :(得分:0)

看到这个警告真令人讨厌。与此同时,您不想关闭警告。所以我想也许提供一个更改代码以摆脱它的例子是有用的。以下是我更改HWIOAuthBundle的{​​{1}}课程的方法。 首先,我改变了OAuthUtils

/vendor/hwi/oauth-bundle/HWI/Bundle/OAuthBundle/Resources/config/oauth.html

到此:

<service id="hwi_oauth.security.oauth_utils" class="%hwi_oauth.security.oauth_utils.class%">
    <argument type="service" id="security.http_utils" />
    <argument type="service" id="security.context" />
    <argument>%hwi_oauth.connect%</argument>
</service>

现在我们必须在<service id="hwi_oauth.security.oauth_utils" class="%hwi_oauth.security.oauth_utils.class%"> <argument type="service" id="security.http_utils" /> <argument type="service" id="security.authorization_checker" /> <argument>%hwi_oauth.connect%</argument> </service> 类中更改它:

    use Symfony\Component\Security\Core\SecurityContextInterface;
    ...

    /**
     * @var SecurityContextInterface
     */
    private $securityContext;

    /**
     * @param HttpUtils                $httpUtils
     * @param SecurityContextInterface $securityContext
     * @param boolean                  $connect
     */
    public function __construct(HttpUtils $httpUtils, SecurityContextInterface $securityContext, $connect)
    {
        $this->httpUtils       = $httpUtils;
        $this->securityContext = $securityContext;
        $this->connect         = $connect;
    }

到此:

    use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
    ...

    /**
     * @var AuthorizationChecker
     */
    private $authorizationChecker;

    /**
     * @param HttpUtils                $httpUtils
     * @param AuthorizationChecker     $authorizationChecker
     * @param boolean                  $connect
     */
    public function __construct(HttpUtils $httpUtils, AuthorizationChecker $authorizationChecker, $connect)
    {
        $this->httpUtils            = $httpUtils;
        $this->authorizationChecker = $authorizationChecker;
        $this->connect              = $connect;
    }

然后我在使用/vendor/hwi/oauth-bundle/HWI/Bundle/OAuthBundle/Security/OAuthUtils的地方进行了更改。用securityContext替换它。

    public function getAuthorizationUrl(Request $request, $name, $redirectUrl = null, array $extraParameters = array())
    {
        $resourceOwner = $this->getResourceOwner($name);
        if (null === $redirectUrl) {
            if (!$this->connect || !$this->authorizationChecker->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
                $redirectUrl = $this->httpUtils->generateUri($request, $this->ownerMap->getResourceOwnerCheckPath($name));
            } else {
                $redirectUrl = $this->getServiceAuthUrl($request, $resourceOwner);
            }
        }

        return $resourceOwner->getAuthorizationUrl($redirectUrl, $extraParameters);
    }

使用AuthorizationChecker替换SecurityContext的原因是因为在这种情况下只使用了isGranted方法。也许您可以用TokenStorage替换它,或者如果您的情况需要,可以同时使用AuthorizationChecker和TokenStorage。