fredericmay
8/18/2017 - 12:47 PM

Event Subscriber: Redirects on 403 access denied kernel exceptions

Event Subscriber: Redirects on 403 access denied kernel exceptions

services:
  mymodule.subscriber:
    class: Drupal\my_module\EventSubscriber\Subscriber
    tags:
      - { name: event_subscriber }
<?php

namespace Drupal\my_module\EventSubscriber;

use Drupal\Core\Url;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;

/**
 * Redirect 403 to User Login event subscriber.
 */
class Subscriber implements EventSubscriberInterface {

  /**
   * {@inheritdoc}
   *
   * The priority for the exception must be as low as possible this subscriber
   * to respond with AccessDeniedHttpException.
   */
  public static function getSubscribedEvents() {
    return [
      KernelEvents::EXCEPTION => 'onKernelException',
    ];
  }

  /**
   * Redirects on 403 Access Denied kernel exceptions.
   *
   * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event
   *   The Event to process.
   *
   * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
   *   Thrown when the access is denied and redirects to user login page.
   */
  public function onKernelException(GetResponseEvent $event) {
    $exception = $event->getException();
    if (!($exception instanceof AccessDeniedHttpException)) {
      return;
    }

    $url = Url::fromRoute('user.login')->toString();
    $response = new RedirectResponse($url);
    $event->setResponse($response);
  }

}