Подтвердить что ты не робот

Класс Symfony 2 SecurityContext устарел

Я получаю следующую ошибку, когда пытаюсь найти приложение/пример в демонстрации symfony

Ошибка: класс Symfony\Component\Security\Core\SecurityContext устарел с версии 2.6 и будет удален в версии 3.0. использование Symfony\Component\Security\Основные\Authentication\Токен\Storage\TokenStorage или Symfony\Component\Security\Core\Authorization\AuthorizationChecker вместо этого.

Сервер возвращает правильный ответ с кодом статуса 200.

Я ничего не нашел в Google об этом. Кто-нибудь сталкивается с этой ошибкой раньше и/или знает, как ее исправить?

4b9b3361

Ответ 1

Объяснение

Начиная с Symfony 2.6, SecurityContext получил разделение на TokenStorage и AuthorizationChecker (см.: Symfony Blog - "Новое в Symfony 2.6: Улучшения компонентов безопасности" ).

Основной причиной этого было предотвращение циклической ссылки, которая происходила довольно часто при вводе 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.context или SecurityContext в вашем исходном коде (включая каталог поставщика).

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

Ответ 2

Это не правильная ошибка, просто предупреждение.

Устаревший класс - это класс, который планируется удалить в будущих выпусках (в этом случае Symfony).

Он предлагает вам прекратить использовать его и указывает на новый класс (и заменяет), TokenStorage и AuthorizationChecker, который будет выполняться полностью для выполнения тех же задач.

Ответ 3

Это так раздражает, чтобы увидеть это предупреждение. В то же время вы не хотите отключать предупреждения. Поэтому я подумал, что, может быть, полезно привести пример изменения кода, чтобы избавиться от него. Вот как я изменил класс HWIOAuthBundle 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>

Теперь мы должны изменить его в классе /vendor/hwi/oauth-bundle/HWI/Bundle/OAuthBundle/Security/OAuthUtils следующим образом:

    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;
    }

Затем я вносил изменения, когда использовался securityContext. Замените его на authorizationChecker.

    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);
    }

Причина замены SecurityContext на AuthorizationChecker заключается в том, что в этом случае используется только метод Granted. Возможно, вы можете заменить его TokenStorage или использовать как AuthorizationChecker, так и TokenStorage, если вам нужно для вашего дела.