[英]Why do I get "An error occurred while loading the web debug toolbar." when using this Event Subscriber?
我正在創建配置的維護頁面。
我創建了一個事件訂閱者:
public function onKernelRequest(RequestEvent $event)
{
$maintenance = $this->container->hasParameter('maintenance') ? $this->container->getParameter('maintenance') : false;
$underMaintenanceUntil = $this->container->hasParameter('underMaintenanceUntil') ? $this->container->getParameter('underMaintenanceUntil') : false;
if (!$event->isMasterRequest()){
return;
}
$debug = in_array($this->container->get('kernel')->getEnvironment(), ['test','dev']);
$uri = $event->getRequest()->getRequestUri();
if ($uri == '/login' || $uri == '/logout') {
return;
}
if ($maintenance && !$debug && !$this->container->get('security.authorization_checker')->isGranted('ROLE_ADMIN')) {
$engine = $this->container->get('twig');
$content = $engine->render('pages/maintenance.html.twig', array('underMaintenanceUntil' => $underMaintenanceUntil));
$event->setResponse(new Response($content, 503));
$event->stopPropagation();
}
}
並且分析器欄不起作用。 我得到
加載 Web 調試工具欄時出錯。
在日志中:
[申請] 10 月 5 日 08:24:41 |INFO | 請求匹配的路由“_wdt”。 method="GET" request_uri="https://localhost:8001/_wdt/914ef7" route="_wdt" route_parameters={"_controller":"web_profiler.controller.profiler::toolbarAction","_route":"_wdt" ,"token":"914ef7"} [申請] 10 月 5 日 08:24:41 |CRITICA| 請求未捕獲的 PHP 異常 Symfony\\Component\\Security\\Core\\Exception\\AuthenticationCredentialsNotFoundException:“令牌存儲不包含身份驗證令牌。一個可能的原因可能是沒有為此 URL 配置防火牆。” 在 /home/marcin/projects/indali/vendor/symfony/security-core/Authorization/AuthorizationChecker.php 第 52 行
即使我輸入/login
page 我也會得到同樣的錯誤。 if ($uri == '/login' || $uri == '/logout') {return;}
是登錄 uri,難道這不應該阻止不執行進一步的代碼嗎?
這個$this->container->get('security.authorization_checker')->isGranted('ROLE_ADMIN')
產生我的錯誤,因為在開發防火牆中沒有身份驗證令牌。 我可以檢查令牌是否存在,但為什么我的代碼不起作用?。
您的代碼不起作用,因為探查器是從主請求到/login
或/logout
的單獨請求。
分析器欄通過 AJAX 請求加載到不同的 URL。 如果您檢查安全配置,默認值通常是:
dev:
pattern: '^/(_(profiler|wdt)|css|images|js)/'
security: false
Profiler 調用是通過_profiler
或_wdt
。 因此,您對login
或logout
URL 的檢查對此logout
。 它影響主要請求,但不影響分析器欄請求:
一些選擇是,從更糟到更好:
正如您所提到的,檢查令牌是否不為空,但這可能無法按您的預期工作,因為它最終會允許匿名用戶在“維護中”訪問您的站點。
便宜且簡單:根據dev
模式(或至少針對_(profiler|wdt)
檢查請求路徑。 這應該很容易合並到您的代碼中,但是如果您最終添加另一個不安全的防火牆,將來可能會出現問題:
if (preg_match('/^\/(logout|login|_(wdt|profiler))/', $uri) {
return;
}
FirewallConfig
如果你想干凈利落地做,你應該在你的事件訂閱者中注入FirewallMap
,並為請求獲取防火牆。
您需要根據自己的需要進行調整的一個簡單示例:
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component;
class FooSubscriber implements Component\EventDispatcher\EventSubscriberInterface
{
private Security\FirewallMap $firewallMap;
public function __construct(Security\FirewallMap $firewallMap)
{
$this->firewallMap = $firewallMap;
}
public static function getSubscribedEvents(): array
{
return [Component\HttpKernel\KernelEvents::REQUEST => 'onKernelRequest'];
}
public function onKernelRequest(Component\HttpKernel\Event\RequestEvent $event): void
{
if (!$event->isMasterRequest()) {
return;
}
$config = $this->firewallMap->getFirewallConfig($event->getRequest());
if (!$config instanceof Security\FirewallConfig || (!$config->isSecurityEnabled() || $config->allowsAnonymous())) {
return;
}
}
}
由於FirewallMap
不能自動連接,您需要配置服務以顯式注入它:
// services.php
$services->set(FooSubscriber::class)
->args([service('security.firewall.map')]);
或在老式 YAML 中:
# services.yaml
services:
App\FooSubscriber:
arguments:
- '@security.firewall.map'
在您的情況下,您似乎正在取消依賴注入並直接檢索容器。 盡管這是一個不好的做法,如果可能,您應該更改它,使用您當前的代碼,您可以簡單地從$this-container->get('security.firewall.map');
獲取它$this-container->get('security.firewall.map');
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.