Php 为什么我会得到;加载web调试工具栏时出错。”;何时使用此事件订阅服务器?

Php 为什么我会得到;加载web调试工具栏时出错。”;何时使用此事件订阅服务器?,php,symfony,symfony-security,symfony-eventdispatcher,Php,Symfony,Symfony Security,Symfony Eventdispatcher,我正在创建配置维护页面 我创建了一个事件订阅服务器: 公共函数onKernelRequest(RequestEvent$event) { $maintenance=$this->container->hasParameter('maintenance')?$this->container->getParameter('maintenance'):false; $UnderMaintenanceTill=$this->container->hasParameter('UnderMaintenanc

我正在创建配置维护页面

我创建了一个事件订阅服务器:

公共函数onKernelRequest(RequestEvent$event) { $maintenance=$this->container->hasParameter('maintenance')?$this->container->getParameter('maintenance'):false; $UnderMaintenanceTill=$this->container->hasParameter('UnderMaintenanceTill')?$this->container->getParameter('UnderMaintenanceTill'):false; 如果(!$event->isMasterRequest()){ 返回; } $debug=in_数组($this->container->get('kernel')->getEnvironment(),['test','dev']); $uri=$event->getRequest()->getRequestUri(); 如果($uri='/login'| |$uri=='/logout'){ 返回; } 如果($maintenance&&!$debug&&!$this->container->get('security.authorization\u checker')->被授予('ROLE\u ADMIN')){ $engine=$this->container->get('twig'); $content=$engine->render('pages/maintenance.html.twig',array('underMaintenanceUntil'=>$underMaintenanceUntil)); $event->setResponse(新响应($content,503)); $event->stopPropagation(); } } 而且探查器栏不工作。我明白了

加载web调试工具栏时出错

在日志中:

[应用]10月5日08:24:41 |信息|要求匹配路线“_wdt”。 method=“GET”请求\u uri=”https://localhost:8001/_wdt/914ef7" route=“\u wdt” 路由_参数={“_控制器”:“web_profiler.controller.profiler::toolbarAction”,“_路由”:“_wdt”,“令牌”:“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
页面,我也会得到同样的错误。如果($uri='/login'| |$uri=='/logout'){return;}是登录uri,那么这不应该阻止不执行进一步的代码吗


$This->container->get('security.authorization\u checker')->isgrated('ROLE\u ADMIN')
生成我的错误,因为在dev防火墙中没有身份验证令牌。我可以检查令牌是否存在,但为什么我的代码不起作用?

您的代码不起作用,因为探查器是从主请求到
/login
/logout
的单独请求

探查器栏通过AJAX请求加载到不同的URL。如果检查安全配置,默认值通常为:

dev:
模式:“^/((探查器wdt)| css |图像| js)/”
安全性:错误
探查器调用是通过
\u Profiler
\u wdt
进行的调用。因此,您对
登录
注销
URL的检查对此毫无用处。它会影响主请求,但不会影响探查器栏请求:

有些选择是,从差到好:

检查令牌 正如您所提到的,检查令牌是否为null,但这可能不会像您预期的那样工作,因为它最终将允许匿名用户在“维护中”时访问您的站点

检查URL路径 便宜且简单:根据
dev
模式检查请求路径(或者至少根据
(profiler | wdt)
)。这应该很容易合并到代码中,但如果您最终添加了另一个非安全防火墙,则将来可能会出现问题:

if(preg|u match('/^\/(注销|登录| | |(wdt |探查器))/',$uri){
返回;
}
检查请求的
FirewallConfig
如果您想干净地执行此操作,应该在事件订阅服务器中插入
FirewallMap
,并获取请求的防火墙

您需要根据自己的需要调整的一个简单示例:

使用Symfony\Bundle\SecurityBundle\Security;
使用Symfony\Component;
FooSubscriber类实现组件\EventDispatcher\EventSubscriberInterface
{
私有安全\FirewallMap$FirewallMap;
公共函数构造(安全\FirewallMap$FirewallMap)
{
$this->firewallMap=$firewallMap;
}
公共静态函数getSubscribedEvents():数组
{
返回[Component\HttpKernel\KernelEvents::REQUEST=>onKernelRequest'];
}
公共函数onKernelRequest(Component\HttpKernel\Event\RequestEvent$Event):void
{
如果(!$event->isMasterRequest()){
返回;
}
$config=$this->firewallMap->getFirewallConfig($event->getRequest());
如果(!$config instanceof Security\FirewallConfig | |(!$config->isSecurityEnabled()| |$config->allowsAnonymous()){
返回;
}
}
}
由于
FirewallMap
不是自动连线的,因此您需要配置服务以显式插入它:

//services.php
$services->set(FooSubscriber::class)
->args([service('security.firewall.map'));
或者在旧式YAML中:

#services.yaml
服务:
App\foo订户:
论据:
-“@security.firewall.map”

在您的情况下,似乎您正在取消依赖项注入并直接检索容器。尽管这是一种不好的做法,如果可能,您应该更改它,但使用当前代码,您只需从
$this container->get('security.firewall.map')获取它

非常感谢您的澄清,现在一切正常。