[注意]也请参阅最终解决方法,向下滚动
经过12个小时的轰炸和阅读大量材料后,我放弃了并要求别人帮我解决“安全上下文不包含身份验证令牌。一个可能的原因可能是没有为防火墙配置防火墙这个网址。)“问题。如何将安全上下文正确传递给我的自定义处理程序?
我有以下设置:
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 /控制器/ 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 /控制器/ 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没有任何问题,因为没有添加任何安全性,但是为登录成员显示不同的一个让我感到痛苦,所以请提供建议。谢谢!
*最终解决方法*
的Acme / MainBundle /控制器/ 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.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 /事件监听/ 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 :(得分:3)
安全逻辑在路由逻辑之后执行(在2.1之前,之前执行)。这意味着路由器抛出的404错误无法使用安全性,因为还没有关于安全性的信息。
当然,你也可以在安全信息可用的控制器中抛出404错误。要使它在任何情况下都可用,请检查安全上下文是否可用并设置,如果没有,只需渲染未登录的模板