3 namespace Drupal\Core\Authentication;
5 use Drupal\Core\Routing\RouteMatch;
6 use Symfony\Component\HttpFoundation\Request;
9 * Manager for authentication.
11 * On each request, let all authentication providers try to authenticate the
12 * user. The providers are iterated according to their priority and the first
13 * provider detecting credentials for its method wins. No further provider will
16 * If no provider set an active user then the user is set to anonymous.
18 class AuthenticationManager implements AuthenticationProviderInterface, AuthenticationProviderFilterInterface, AuthenticationProviderChallengeInterface {
21 * The authentication provider collector.
23 * @var \Drupal\Core\Authentication\AuthenticationCollectorInterface
25 protected $authCollector;
28 * Creates a new authentication manager instance.
30 * @param \Drupal\Core\Authentication\AuthenticationCollectorInterface $auth_collector
31 * The authentication provider collector.
33 public function __construct(AuthenticationCollectorInterface $auth_collector) {
34 $this->authCollector = $auth_collector;
40 public function applies(Request $request) {
41 return (bool) $this->getProvider($request);
47 public function authenticate(Request $request) {
48 $provider_id = $this->getProvider($request);
49 $provider = $this->authCollector->getProvider($provider_id);
52 return $provider->authenticate($request);
61 public function appliesToRoutedRequest(Request $request, $authenticated) {
65 $result = $this->applyFilter($request, $authenticated, $this->getProvider($request));
68 foreach ($this->authCollector->getSortedProviders() as $provider_id => $provider) {
69 if ($this->applyFilter($request, $authenticated, $provider_id)) {
82 public function challengeException(Request $request, \Exception $previous) {
83 $provider_id = $this->getChallenger($request);
86 $provider = $this->authCollector->getProvider($provider_id);
87 return $provider->challengeException($request, $previous);
92 * Returns the id of the authentication provider for a request.
94 * @param \Symfony\Component\HttpFoundation\Request $request
95 * The incoming request.
98 * The id of the first authentication provider which applies to the request.
99 * If no application detects appropriate credentials, then NULL is returned.
101 protected function getProvider(Request $request) {
102 foreach ($this->authCollector->getSortedProviders() as $provider_id => $provider) {
103 if ($provider->applies($request)) {
110 * Returns the ID of the challenge provider for a request.
112 * @param \Symfony\Component\HttpFoundation\Request $request
113 * The incoming request.
115 * @return string|null
116 * The ID of the first authentication provider which applies to the request.
117 * If no application detects appropriate credentials, then NULL is returned.
119 protected function getChallenger(Request $request) {
120 foreach ($this->authCollector->getSortedProviders() as $provider_id => $provider) {
121 if (($provider instanceof AuthenticationProviderChallengeInterface) && !$provider->applies($request) && $this->applyFilter($request, FALSE, $provider_id)) {
128 * Checks whether a provider is allowed on the given request.
130 * If no filter is registered for the given provider id, the default filter
133 * @param \Symfony\Component\HttpFoundation\Request $request
134 * The incoming request.
135 * @param bool $authenticated
136 * Whether or not the request is authenticated.
137 * @param string $provider_id
138 * The id of the authentication provider to check access for.
141 * TRUE if provider is allowed, FALSE otherwise.
143 protected function applyFilter(Request $request, $authenticated, $provider_id) {
144 $provider = $this->authCollector->getProvider($provider_id);
146 if ($provider && ($provider instanceof AuthenticationProviderFilterInterface)) {
147 $result = $provider->appliesToRoutedRequest($request, $authenticated);
150 $result = $this->defaultFilter($request, $provider_id);
157 * Default implementation of the provider filter.
159 * Checks whether a provider is allowed as per the _auth option on a route. If
160 * the option is not set or if the request did not match any route, only
161 * providers from the global provider set are allowed.
163 * If no filter is registered for the given provider id, the default filter
166 * @param \Symfony\Component\HttpFoundation\Request $request
167 * The incoming request.
168 * @param string $provider_id
169 * The id of the authentication provider to check access for.
172 * TRUE if provider is allowed, FALSE otherwise.
174 protected function defaultFilter(Request $request, $provider_id) {
175 $route = RouteMatch::createFromRequest($request)->getRouteObject();
176 $has_auth_option = isset($route) && $route->hasOption('_auth');
178 if ($has_auth_option) {
179 return in_array($provider_id, $route->getOption('_auth'));
182 return $this->authCollector->isGlobal($provider_id);