2015-05-28 15 views
10

Trong ứng dụng Symfony2 của tôi, tôi đã xây dựng một trình lắng nghe ngoại lệ cho phép tôi biết về các lỗi chưa được xử lý.Symfony: Không tìm thấy mã thông báo trong SecurityContext cho tuyến đường phía sau tường lửa

tôi nhận tin nhắn về lỗi sau khi chương trình đang truy cập trang web của tôi, đó là đằng sau một bức tường lửa:

A Token was not found in the SecurityContext. 

Tôi cũng lấy các dữ liệu sau:

User agent Mozilla/5.0 (compatible; AhrefsBot/5.0; +http://ahrefs.com/robot/) 
Trace as string #0 /home/foodmeup.net/production/releases/20150527141710/app/cache/prod/classes.php(2951): Symfony\Component\Security\Http\Firewall\AccessListener->handle(Object(Symfony\Component\HttpKernel\Event\GetResponseEvent)) 
#1 [internal function]: Symfony\Component\Security\Http\Firewall->onKernelRequest(Object(Symfony\Component\HttpKernel\Event\GetResponseEvent), 'kernel.request', Object(Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher)) 
#2 /home/foodmeup.net/production/releases/20150527141710/app/cache/prod/classes.php(2205): call_user_func(Array, Object(Symfony\Component\HttpKernel\Event\GetResponseEvent), 'kernel.request', Object(Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher)) 
#3 /home/foodmeup.net/production/releases/20150527141710/app/cache/prod/classes.php(2138): Symfony\Component\EventDispatcher\EventDispatcher->doDispatch(Array, 'kernel.request', Object(Symfony\Component\HttpKernel\Event\GetResponseEvent)) 
#4 /home/foodmeup.net/production/releases/20150527141710/app/cache/prod/classes.php(2299): Symfony\Component\EventDispatcher\EventDispatcher->dispatch('kernel.request', Object(Symfony\Component\HttpKernel\Event\GetResponseEvent)) 
#5 /home/foodmeup.net/production/releases/20150527141710/app/bootstrap.php.cache(3017): Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.request', Object(Symfony\Component\HttpKernel\Event\GetResponseEvent)) 
#6 /home/foodmeup.net/production/releases/20150527141710/app/bootstrap.php.cache(2990): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1) 
#7 /home/foodmeup.net/production/releases/20150527141710/app/bootstrap.php.cache(3139): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) 
#8 /home/foodmeup.net/production/releases/20150527141710/app/bootstrap.php.cache(2383): Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) 
#9 /home/foodmeup.net/production/releases/20150527141710/web/app.php(28): Symfony\Component\HttpKernel\Kernel->handle(Object(Symfony\Component\HttpFoundation\Request)) 
#10 {main} 

Điều này xảy ra trên về tất cả trang web của tôi kể từ lần cập nhật cuối cùng nhưng tôi không thể tìm ra vấn đề là gì. Nếu tôi tự truy cập trang, không có vấn đề gì, không có ngoại lệ nào được nêu ra.

Sự hiểu biết của tôi về tường lửa mà tôi thiết lập là trong trường hợp ai đó cố gắng truy cập tài nguyên được bảo vệ, anh ta được chuyển hướng đến trang đăng nhập mà không bị lỗi. Ở đây, tôi lo sợ rằng một số người dùng có thể truy cập trang lỗi thay vì được chuyển hướng đến trang đăng nhập. Và khi tôi muốn tái tạo lỗi bằng cách truy cập vào người giới thiệu từ khi lỗi được ném, tôi được chuyển hướng chính xác vì vậy tôi không hiểu các trường hợp khi lỗi được ném so với người dùng được chuyển hướng.

EDIT:

My dịch vụ ngoại lệ nghe:

exception_listener: 
    class: %exception_listener.class% 
    arguments: [@router, @session, @security.token_storage, @email_manager, @doctrine, "@=service('kernel').getEnvironment()", @security.authorization_checker] 
    tags: 
     - { name: kernel.event_listener, event: kernel.exception, method: onKernelException, priority: 250 } 

tôi đang ngoại lệ nghe:

<?php 

namespace AppBundle\EventListener; 

use AppBundle\Application\Core\EmailManager; 
use AppBundle\Application\Core\JournalManager; 
use AppBundle\Entity\User\User; 
use AppBundle\Security\Voter\SubscriptionVoter; 
use Doctrine\Bundle\DoctrineBundle\Registry; 
use Symfony\Bundle\FrameworkBundle\Routing\Router; 
use Symfony\Component\HttpFoundation\RedirectResponse; 
use Symfony\Component\HttpFoundation\Request; 
use Symfony\Component\HttpFoundation\Session\Session; 
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; 
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage; 
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker; 


class ExceptionListener 
{ 
    /** 
    * @var Router 
    */ 
    private $router; 

    /** 
    * @var Session 
    */ 
    private $session; 

    /** 
    * @var TokenStorage 
    */ 
    private $tokenStorage; 

    /** 
    * @var EmailManager 
    */ 
    private $emailManager; 

    /** 
    * @var null 
    */ 
    private $environment; 

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

    public function __construct(Router $router, Session $session, TokenStorage $tokenStorage, EmailManager $emailManager, Registry $doctrine ,$environment=null, AuthorizationChecker $authorizationChecker) 
    { 
     $this->router = $router; 
     $this->session = $session; 
     $this->tokenStorage = $tokenStorage; 
     $this->emailManager = $emailManager; 
     $this->environment = $environment; 
     $this->authorizationChecker = $authorizationChecker; 
     $this->doctrine = $doctrine; 
    } 

    public function onKernelException(GetResponseForExceptionEvent $event) 
    { 
     try { 
      /** @var $exception */ 
      $exception = $event->getException(); 
      $request = $event->getRequest(); 
      $referer = $request->headers->get('referer'); 

      $manager = $this->doctrine->getManager('logging'); 
      $journalManager = new JournalManager($manager); 

      if($exception->getCode() == 403) 
      { 
       if ($this->authorizationChecker->isGranted(SubscriptionVoter::HAS_SUBSCRIPTION) && !$this->authorizationChecker->isGranted(SubscriptionVoter::SUBSCRIPTION_VALID)) 
       { 
        $this->session->getFlashBag()->add('warning',"La page précédente n'est pas accessible avec ce portfolio car le paiement n'est pas à jour. Vous devez actualiser votre paiement."); 
        $response = new RedirectResponse($this->router->generate('renew_subscription')); 
       } 
       else 
       { 
        $this->session->getFlashBag()->add('warning',"La page précédente n'est pas accessible avec vos droits d'accès et vous avez été redirigé vers l'accueil du site."); 
        $response = new RedirectResponse($this->router->generate('home')); 
       } 

       $event->setResponse($response); 
      } 
      elseif ($exception->getMessage() == "Couldn't connect to host, Elasticsearch down?" || $exception->getCode() == 52) 
      { 
       $this->session->getFlashBag()->add('warning', "La service de recherche du site a arrêté de fonctionner. Renouvellez votre dernière action si celle si n'a pas été suivie d'effet d'ici 2 minutes."); 
       $event->setResponse(new RedirectResponse($request->headers->get('referer') ?: $this->router->generate('home'))); 
      } 
      elseif (
       !($exception->getCode() == 404 && !$referer) && 
       !($this->contains($exception->getMessage(), array('object not found', 'A Token was not found in the SecurityContext', 'No route found for')) && !strpos($referer, 'foodmeup')) && 
       !in_array($this->environment, array('dev', 'test')) && 
       !$journalManager->errorExists($exception, $request->getUri(), 1) 
      ) 
      { 
       $user = is_object($this->tokenStorage->getToken()) ? $this->tokenStorage->getToken()->getUser() : null; 
       $user = $user instanceOf User ? $user : null; 
       $code = $exception->getCode(); 

       $this->emailManager->sendEmail(
        '[email protected]', 
        '[email protected]', 
        ':Core/Email:error.html.twig', 
        "Une erreur $code s'est produite sur le site", 
        array(
         'date' => new \DateTime(), 
         'user' => $user, 
         'exception' => $exception, 
         'referer' => $request->headers->get('referer'), 
         'current' => $request->getUri(), 
         'user_agent' => $_SERVER['HTTP_USER_AGENT'] 
        ) 
       ); 

       $journalManager->addErrorLog($exception, $request->getUri()); 
      } 
     } catch (\Exception $e) 
     { 
     } 

    } 

    private function contains($str, array $arr) 
    { 
     foreach($arr as $a) { 
      if (stripos($str,$a) !== false) return true; 
     } 
     return false; 
    } 
} 

tường lửa của tôi:

firewalls: 
    dev: 
     pattern: ^/(_(profiler|wdt)|css|images|js)/ 
     security: false 
    guest: 
     pattern:  /(public/|$|genemu-captcha-refresh|media/cache/) 
     anonymous:  true 
     context:  main_auth 
    main: 
     pattern:  ^/ 
     anonymous:  false 
     provider:  main 
     context:  main_auth 
     switch_user: { role: ROLE_ADMIN, parameter: _switch_user_parameter } 
     form_login: 
      login_path: fos_user_security_login 
      check_path: fos_user_security_check 
      success_handler: authentication_site_handler 
     logout: 
      path:  fos_user_security_logout 
      target: /
     remember_me: 
      key:  "%secret%" 
      lifetime: 86400 #en secondes 
      path: /
      domain: ~ # Prend la valeur par défaut du domaine courant depuis $_SERVER 
     oauth: 
      remember_me: true 
      resource_owners: 
       facebook:   "/loginhwi/check-facebook" 
       github:    "/loginhwi/check-github" 
       google:    "/loginhwi/check-google" 
       twitter:   "/loginhwi/check-twitter" 
       linkedin:   "/loginhwi/check-linkedin" 
       flickr:    "/loginhwi/check-flickr" 
      login_path:  fos_user_security_login 
      check_path:  fos_user_security_check 
      failure_path:  fos_user_security_login 
      success_handler: authentication_site_handler 
      oauth_user_provider: 
       service: fosubuser.provider 

chính xác:

  • EmailManager chỉ gửi email có các tham số nhất định. nó hoạt động tốt
  • Các journalManager chỉ ghi lại lỗi và giúp tôi lọc ra các lỗi đã đăng nhập
+0

Bạn có thể cung cấp mã của người nghe ngoại lệ của mình không? – kba

+0

tốt, người nghe ngoại lệ chỉ xử lý ngoại lệ, phải không? ở đây tôi muốn ngăn chặn ngoại lệ này là giải quyết vấn đề trước. Tôi vẫn có thể đăng nó nếu bạn thấy nó hữu ích nhưng tôi đoán nó sẽ trở thành một sự mất tập trung –

+0

Nó không rõ ràng loại câu trả lời bạn đang mong đợi để có được: ngoại lệ ** IS ** ném khi bạn cố gắng truy cập một bảo vệ tài nguyên không có mã thông báo hoạt động. Nếu bạn không muốn nó xuất hiện - đừng xử lý nó. – zerkms

Trả lời

4

Don không lo lắng về trường hợp này/lỗi. Khi bạn tự mình kiểm tra trường hợp, bạn có hành vi mong đợi (chuyển hướng đến trang đăng nhập) như bất kỳ người lướt sóng "thực" nào khác.

Sau đó

đại diện người dùng Mozilla/5.0 (compatible; AhrefsBot/5.0; + http://ahrefs.com/robot/)

Bạn có thể thấy rằng trang web được yêu cầu của Ahrefs bot. Và khi bạn chuyển hướng đến các trang khác là người lướt thực, nó sử dụng hành động "tiêu đề". Nhưng chương trình không xử lý tiêu đề. Vì vậy, thực sự nó là một lỗi mà các lập trình viên nghiệp dư làm thường xuyên. Họ đặt một cái gì đó như

if($notallowed){ 
header('Location: /login'); 
} 
//... only logged stuff ...// 

và sau đó nó hoạt động cho những người lướt sóng "thực", nhưng bot có thể đi qua và tiếp cận "nội dung đã đăng nhập". Vì vậy, trong trường hợp này nó hoặc là cần "chết" lệnh ngay sau khi tiêu đề (trong phong cách xấu mà phải không bao giờ người dùng) hoặc ném ngoại lệ (trong phong cách tốt).

Vì vậy, kết luận: Bạn đã đề cập rằng gần đây bạn đã có ngoại lệ sau khi bạn thay đổi mã, nhưng có thể bot bắt đầu thu thập thông tin gì đó mới chưa được thu thập thông tin trước đó. Vì vậy, có lẽ bạn nên thêm quy tắc để bỏ qua ngoại lệ đó vì nó chỉ được áp dụng cho các bot. Nhưng tất nhiên bạn cũng nên xem lại những thay đổi gần đây. Ngoài ra, bạn có thể xem lại nhật ký ngoại lệ như vậy và kiểm tra tác nhân người dùng để đảm bảo rằng nó chỉ được áp dụng cho các bot.

+0

cảm ơn, tôi nghĩ rằng nó có liên quan đến những thứ bot. Tôi đã adpated người nghe để loại trừ chương trình, tôi sẽ trở lại để nói nếu đó là điều cần làm –

Các vấn đề liên quan