Updated Drupal to 8.6. This goes with the following updates because it's possible...
[yaffs-website] / web / core / lib / Drupal / Core / EventSubscriber / AuthenticationSubscriber.php
1 <?php
2
3 namespace Drupal\Core\EventSubscriber;
4
5 use Drupal\Core\Authentication\AuthenticationProviderFilterInterface;
6 use Drupal\Core\Authentication\AuthenticationProviderChallengeInterface;
7 use Drupal\Core\Authentication\AuthenticationProviderInterface;
8 use Drupal\Core\Session\AccountProxyInterface;
9 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
10 use Symfony\Component\HttpKernel\Event\GetResponseEvent;
11 use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
12 use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
13 use Symfony\Component\HttpKernel\HttpKernelInterface;
14 use Symfony\Component\HttpKernel\KernelEvents;
15
16 /**
17  * Authentication subscriber.
18  *
19  * Trigger authentication during the request.
20  */
21 class AuthenticationSubscriber implements EventSubscriberInterface {
22
23   /**
24    * Authentication provider.
25    *
26    * @var \Drupal\Core\Authentication\AuthenticationProviderInterface
27    */
28   protected $authenticationProvider;
29
30   /**
31    * Authentication provider filter.
32    *
33    * @var \Drupal\Core\Authentication\AuthenticationProviderFilterInterface|null
34    */
35   protected $filter;
36
37   /**
38    * Authentication challenge provider.
39    *
40    * @var \Drupal\Core\Authentication\AuthenticationProviderChallengeInterface|null
41    */
42   protected $challengeProvider;
43
44   /**
45    * Account proxy.
46    *
47    * @var \Drupal\Core\Session\AccountProxyInterface
48    */
49   protected $accountProxy;
50
51   /**
52    * Constructs an authentication subscriber.
53    *
54    * @param \Drupal\Core\Authentication\AuthenticationProviderInterface $authentication_provider
55    *   An authentication provider.
56    * @param \Drupal\Core\Session\AccountProxyInterface $account_proxy
57    *   Account proxy.
58    */
59   public function __construct(AuthenticationProviderInterface $authentication_provider, AccountProxyInterface $account_proxy) {
60     $this->authenticationProvider = $authentication_provider;
61     $this->filter = ($authentication_provider instanceof AuthenticationProviderFilterInterface) ? $authentication_provider : NULL;
62     $this->challengeProvider = ($authentication_provider instanceof AuthenticationProviderChallengeInterface) ? $authentication_provider : NULL;
63     $this->accountProxy = $account_proxy;
64   }
65
66   /**
67    * Authenticates user on request.
68    *
69    * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event
70    *   The request event.
71    *
72    * @see \Drupal\Core\Authentication\AuthenticationProviderInterface::authenticate()
73    */
74   public function onKernelRequestAuthenticate(GetResponseEvent $event) {
75     if ($event->getRequestType() === HttpKernelInterface::MASTER_REQUEST) {
76       $request = $event->getRequest();
77       if ($this->authenticationProvider->applies($request)) {
78         $account = $this->authenticationProvider->authenticate($request);
79         if ($account) {
80           $this->accountProxy->setAccount($account);
81           return;
82         }
83       }
84       // No account has been set explicitly, initialize the timezone here.
85       date_default_timezone_set(drupal_get_user_timezone());
86     }
87   }
88
89   /**
90    * Denies access if authentication provider is not allowed on this route.
91    *
92    * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event
93    *   The request event.
94    */
95   public function onKernelRequestFilterProvider(GetResponseEvent $event) {
96     if (isset($this->filter) && $event->getRequestType() === HttpKernelInterface::MASTER_REQUEST) {
97       $request = $event->getRequest();
98       if ($this->authenticationProvider->applies($request) && !$this->filter->appliesToRoutedRequest($request, TRUE)) {
99         throw new AccessDeniedHttpException('The used authentication method is not allowed on this route.');
100       }
101     }
102   }
103
104   /**
105    * Respond with a challenge on access denied exceptions if appropriate.
106    *
107    * On a 403 (access denied), if there are no credentials on the request, some
108    * authentication methods (e.g. basic auth) require that a challenge is sent
109    * to the client.
110    *
111    * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event
112    *   The exception event.
113    */
114   public function onExceptionSendChallenge(GetResponseForExceptionEvent $event) {
115     if (isset($this->challengeProvider) && $event->getRequestType() === HttpKernelInterface::MASTER_REQUEST) {
116       $request = $event->getRequest();
117       $exception = $event->getException();
118       if ($exception instanceof AccessDeniedHttpException && !$this->authenticationProvider->applies($request) && (!isset($this->filter) || $this->filter->appliesToRoutedRequest($request, FALSE))) {
119         $challenge_exception = $this->challengeProvider->challengeException($request, $exception);
120         if ($challenge_exception) {
121           $event->setException($challenge_exception);
122         }
123       }
124     }
125   }
126
127   /**
128    * {@inheritdoc}
129    */
130   public static function getSubscribedEvents() {
131     // The priority for authentication must be higher than the highest event
132     // subscriber accessing the current user. Especially it must be higher than
133     // LanguageRequestSubscriber as LanguageManager accesses the current user if
134     // the language module is enabled.
135     $events[KernelEvents::REQUEST][] = ['onKernelRequestAuthenticate', 300];
136
137     // Access check must be performed after routing.
138     $events[KernelEvents::REQUEST][] = ['onKernelRequestFilterProvider', 31];
139     $events[KernelEvents::EXCEPTION][] = ['onExceptionSendChallenge', 75];
140     return $events;
141   }
142
143 }