2013-12-23 2 views
1

[Примечание] тоже см окончательный обходной путь, прокрутите внизSymfony2 Пользовательские исключения и маркера проверки подлинности

после 12 часов тряс головой и читать тонны материалов, которые я дал и просить кого-то, чтобы помочь мне, как решить " Контекст безопасности не содержит токен аутентификации. Возможна одна причина, по которой для этого URL-адреса не установлен брандмауэр.) « проблема.

Как я могу правильно передать контекст безопасности своему пользовательскому обработчику?

У меня после установки:

  • Env: прод
  • Debug: ложному

security.yml

jms_security_extra: 
    secure_all_services: false 
    expressions: true 

security: 
    encoders: 
     Symfony\Component\Security\Core\User\User: plaintext 
     path\to\SsoAccount: plaintext 

    role_hierarchy: 
     ROLE_ADMIN:  ROLE_USER 
     ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH] 

    providers: 
     sso: 
      id: sso_account_provider 

    firewalls: 
     dev: 
      pattern: ^/(_(profiler|wdt)|css|images|js)/ 
      security: false 

     sso: 
      pattern: ^/ 
      logout: 
       path: sso_logout 
       target: homepage 
      anonymous: ~ 

    access_control: ~ 

config.yml

# Twig Configuration 
twig: 
    exception_controller: "acme.controller.exception_controller:showAction" 
    debug:   "%kernel.debug%" 
    strict_variables: "%kernel.debug%" 
    globals: 
     project_url: "%cfg_project_url%" 
     sso_server: "%cfg_sso_server%" 
     sso_server_admin: "%cfg_sso_server_admin%" 
     google_drive_api_key: "%cfg_google_drive_api_key%" 
     oauth_client_id:  "%cfg_oauth_client_id%" 
    form: 
     resources: 
      - "MainBundle:Form:fields.html.twig" 

services: 
    acme.controller.exception_controller: 
     parent: twig.controller.exception 
     class: Acme\MainBundle\Controller\ExceptionController 
     arguments: ["@security.context"] 
     calls: 
      - [ 'setContainer', ['@service_container']] 
      - [ 'setSecurityContext', ['@security.context']] 

Acme/MainBundle/Controller/ExceptionController.php

<?php 
namespace Acme\MainBundle\Controller; 

use Symfony\Bundle\TwigBundle\Controller\ExceptionController as BaseExceptionController; 
use Symfony\Component\DependencyInjection\ContainerInterface; 
use Symfony\Component\HttpFoundation\Request; 
use Symfony\Component\HttpKernel\Exception\FlattenException; 
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; 
use Symfony\Component\Security\Core\SecurityContext; 

class ExceptionController extends BaseExceptionController 
{ 
    protected $securityContext; 
    protected $container; 

    public function setContainer(ContainerInterface $container) 
    { 
     $this->container = $container; 
    } 

    public function setSecurityContext(SecurityContext $context) 
    { 
     $this->securityContext = $context; 
    } 

    public function showAction(
     Request $request, 
     FlattenException $exception, 
     DebugLoggerInterface $logger = null, 
     $format = 'html' 
    ) { 
     $this->exceptionClass = $exception->getClass(); 

     return parent::showAction($request, $exception, $logger, $format); 
    } 

    protected function findTemplate(Request $request, $format, $code, $debug) 
    { 
     /*********************/ 
     /** PROBLEM IS HERE **/ 
     //$user = $this->securityContext->isGranted('ROLE_USER'); 
     /** PROBLEM IS HERE **/ 
     /*********************/ 

     if (!$debug) { 
      return 'MainBundle:Main:error404.html.twig'; 
     } 

     return parent::findTemplate($request, $format, $code, $debug); 
    } 
} 

Acme/MainBundle/Ресурсы/просмотров/Главная/error404.html.twig

{% block body %} 
    {{ render(controller('MainBundle:Main:error404')) }} 
{% endblock %} 

Acme/MainBundle/Controller/MainController.php

/** 
*/ 
public function error404Action() 
{ 
    /** ALWAYS return null **/ 
    $getUser = $this->getUser(); 
    /***********************/ 

    if (!empty($getUser)) { 
     $account = $this->getUser()->getAccountInfo(); 
     $user = $account->Account["0"]->user; 

     return $this->render(
        'MainBundle:Main:error404_loggedin.html.twig', 
         array(
          'account' => $account, 
          'user' => $user, 
         ) 
     ); 
    } 

    return $this->render(
       'MainBundle:Main:error404_not_loggedin.html.twig', 
        array() 
    ); 
} 

Ошибка 404 «не вошла в систему», так как для нее не добавлено никакой безопасности, но отображение другого для зарегистрированных пользователей заставило меня чувствовать себя несчастным, поэтому, пожалуйста, совет. Благодаря!


* Final * Обход


Acme/MainBundle/Controller/MainController.php

/** 
* @Route("/404", name="publicError404") 
*/ 
public function publicError404Action() 
{ 
    $response = new Response(); 
    $response->setStatusCode(404); 

    $templateFile = 'MainBundle:Main:error404_not_loggedin.html.twig'; 
    $templateData = array(); 

    $getUser = $this->getUser(); 
    if (!empty($getUser)) { 
     $templateFile = 'MainBundle:Main:error404_loggedin.html.twig'; 

     $account = $this->getUser()->getAccountInfo(); 
     $user = $account->Account["0"]->user; 

     $templateData['account'] = $account; 
     $templateData['user'] = $user; 
    } 

    $templateData['token']  = $this->getRequest()->getSession()->getId(); 
    $templateData['sso']  = $this->container->getParameter('sso_token'); 
    $templateData['timestamp'] = time(); //date(DATE_RFC822) 

    return $this->render($templateFile, $templateData, $response); 
} 

приложение/Config/config.yml

services: 
    acme.controller.exception_controller: 
     class: Acme\MainBundle\EventListener\NotFoundRouteListener 
     tags: 
      - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest } 
     arguments: [ @router, @service_container, @kernel ] 

Acme/MainBundle/EventListener/NotFoundRouteListener.php

<?php 
namespace Acme\MainBundle\EventListener; 

use Symfony\Component\DependencyInjection\ContainerInterface; 
use Symfony\Component\HttpFoundation\RedirectResponse; 
use Symfony\Component\HttpKernel\Event\GetResponseEvent; 
use Symfony\Component\HttpKernel\Kernel; 
use Symfony\Component\Routing\Router; 

class NotFoundRouteListener 
{ 
    protected $container; 
    protected $router; 
    protected $kernel; 

    public function __construct(Router $router, ContainerInterface $container, Kernel $kernel) 
    { 
     $this->router = $router; 
     $this->container = $container; 
     $this->kernel = $kernel; 
    } 

    public function onKernelRequest(GetResponseEvent $event) 
    { 
     $isProduction = ($this->kernel->getEnvironment() == "prod") ? true : false; 
     $isDebug  = ($this->kernel->isDebug() == true) ? : false; 
     $routeName = $this->container->get('request')->get('_route'); 

     /** 
     * Display only if: 
     *  - env = prod 
     *  - debug = false 
     *  - route = empty 
     */ 
     if ($isProduction && !$isDebug && empty($routeName)) { 
      $url = $this->router->generate('publicError404'); 
      $event->setResponse(new RedirectResponse($url)); 
     } 
    } 
} 

Я не буду вставлять содержимое error404_not_loggedin.html.twig и error404_loggedin.html.twig, так как это не требуется для вопроса и решения ,

+0

Почему у вас есть YAML в XML-файлах? – keyboardSmasher

+0

Они .yml, извините. Зафиксируем это сейчас – RRStoyanov

ответ

3

Логика безопасности выполняется после логики маршрутизации (до версии 2.1, она выполнялась раньше). Это означает, что ошибка 404, создаваемая маршрутизатором, не может использовать безопасность, поскольку пока нет информации о безопасности.

Орех Вы также можете бросить 404 ошибки в контроллере, где доступна информация о безопасности. Чтобы сделать его доступным в любом случае, проверьте, доступен ли контекст безопасности и настроен ли он, а если нет, просто визуализируйте нерегистрируемый шаблон templates

+0

U/пение вашего предложения Создаем обходное решение (добавлено в первый комментарий). Благодаря! – RRStoyanov

Смежные вопросы