Drupal 8.0.0 beta 12. More info: https://www.drupal.org/node/2514176
This commit is contained in:
commit
9921556621
13277 changed files with 1459781 additions and 0 deletions
248
core/lib/Drupal/Core/Authentication/AuthenticationManager.php
Normal file
248
core/lib/Drupal/Core/Authentication/AuthenticationManager.php
Normal file
|
@ -0,0 +1,248 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Authentication\AuthenticationManager.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Authentication;
|
||||
|
||||
use Drupal\Core\Routing\RouteMatch;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Manager for authentication.
|
||||
*
|
||||
* On each request, let all authentication providers try to authenticate the
|
||||
* user. The providers are iterated according to their priority and the first
|
||||
* provider detecting credentials for its method wins. No further provider will
|
||||
* get triggered.
|
||||
*
|
||||
* If no provider set an active user then the user is set to anonymous.
|
||||
*/
|
||||
class AuthenticationManager implements AuthenticationProviderInterface, AuthenticationProviderFilterInterface, AuthenticationProviderChallengeInterface, AuthenticationManagerInterface {
|
||||
|
||||
/**
|
||||
* Array of all registered authentication providers, keyed by ID.
|
||||
*
|
||||
* @var \Drupal\Core\Authentication\AuthenticationProviderInterface[]
|
||||
*/
|
||||
protected $providers;
|
||||
|
||||
/**
|
||||
* Array of all providers and their priority.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $providerOrders = array();
|
||||
|
||||
/**
|
||||
* Sorted list of registered providers.
|
||||
*
|
||||
* @var \Drupal\Core\Authentication\AuthenticationProviderInterface[]
|
||||
*/
|
||||
protected $sortedProviders;
|
||||
|
||||
/**
|
||||
* List of providers which implement the filter interface.
|
||||
*
|
||||
* @var \Drupal\Core\Authentication\AuthenticationProviderFilterInterface[]
|
||||
*/
|
||||
protected $filters;
|
||||
|
||||
/**
|
||||
* List of providers which implement the challenge interface.
|
||||
*
|
||||
* @var \Drupal\Core\Authentication\AuthenticationProviderChallengeInterface[]
|
||||
*/
|
||||
protected $challengers;
|
||||
|
||||
/**
|
||||
* List of providers which are allowed on routes with no _auth option.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $globalProviders;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addProvider(AuthenticationProviderInterface $provider, $provider_id, $priority = 0, $global = FALSE) {
|
||||
$this->providers[$provider_id] = $provider;
|
||||
$this->providerOrders[$priority][$provider_id] = $provider;
|
||||
// Force the builders to be re-sorted.
|
||||
$this->sortedProviders = NULL;
|
||||
|
||||
if ($provider instanceof AuthenticationProviderFilterInterface) {
|
||||
$this->filters[$provider_id] = $provider;
|
||||
}
|
||||
if ($provider instanceof AuthenticationProviderChallengeInterface) {
|
||||
$this->challengers[$provider_id] = $provider;
|
||||
}
|
||||
|
||||
if ($global) {
|
||||
$this->globalProviders[$provider_id] = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function applies(Request $request) {
|
||||
return (bool) $this->getProvider($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function authenticate(Request $request) {
|
||||
$provider_id = $this->getProvider($request);
|
||||
return $this->providers[$provider_id]->authenticate($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function appliesToRoutedRequest(Request $request, $authenticated) {
|
||||
$result = FALSE;
|
||||
|
||||
if ($authenticated) {
|
||||
$result = $this->applyFilter($request, $authenticated, $this->getProvider($request));
|
||||
}
|
||||
else {
|
||||
foreach ($this->getSortedProviders() as $provider_id => $provider) {
|
||||
if ($this->applyFilter($request, $authenticated, $provider_id)) {
|
||||
$result = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function challengeException(Request $request, \Exception $previous) {
|
||||
$provider_id = $this->getChallenger($request);
|
||||
if ($provider_id) {
|
||||
return $this->challengers[$provider_id]->challengeException($request, $previous);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the id of the authentication provider for a request.
|
||||
*
|
||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||
* The incoming request.
|
||||
*
|
||||
* @return string|NULL
|
||||
* The id of the first authentication provider which applies to the request.
|
||||
* If no application detects appropriate credentials, then NULL is returned.
|
||||
*/
|
||||
protected function getProvider(Request $request) {
|
||||
foreach ($this->getSortedProviders() as $provider_id => $provider) {
|
||||
if ($provider->applies($request)) {
|
||||
return $provider_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the id of the challenge provider for a request.
|
||||
*
|
||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||
* The incoming request.
|
||||
*
|
||||
* @return string|NULL
|
||||
* The id of the first authentication provider which applies to the request.
|
||||
* If no application detects appropriate credentials, then NULL is returned.
|
||||
*/
|
||||
protected function getChallenger(Request $request) {
|
||||
if (!empty($this->challengers)) {
|
||||
foreach ($this->getSortedProviders($request, FALSE) as $provider_id => $provider) {
|
||||
if (isset($this->challengers[$provider_id]) && !$provider->applies($request) && $this->applyFilter($request, FALSE, $provider_id)) {
|
||||
return $provider_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a provider is allowed on the given request.
|
||||
*
|
||||
* If no filter is registered for the given provider id, the default filter
|
||||
* is applied.
|
||||
*
|
||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||
* The incoming request.
|
||||
* @param bool $authenticated
|
||||
* Whether or not the request is authenticated.
|
||||
* @param string $provider_id
|
||||
* The id of the authentication provider to check access for.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if provider is allowed, FALSE otherwise.
|
||||
*/
|
||||
protected function applyFilter(Request $request, $authenticated, $provider_id) {
|
||||
if (isset($this->filters[$provider_id])) {
|
||||
$result = $this->filters[$provider_id]->appliesToRoutedRequest($request, $authenticated);
|
||||
}
|
||||
else {
|
||||
$result = $this->defaultFilter($request, $provider_id);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default implementation of the provider filter.
|
||||
*
|
||||
* Checks whether a provider is allowed as per the _auth option on a route. If
|
||||
* the option is not set or if the request did not match any route, only
|
||||
* providers from the global provider set are allowed.
|
||||
*
|
||||
* If no filter is registered for the given provider id, the default filter
|
||||
* is applied.
|
||||
*
|
||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||
* The incoming request.
|
||||
* @param string $provider_id
|
||||
* The id of the authentication provider to check access for.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if provider is allowed, FALSE otherwise.
|
||||
*/
|
||||
protected function defaultFilter(Request $request, $provider_id) {
|
||||
$route = RouteMatch::createFromRequest($request)->getRouteObject();
|
||||
$has_auth_option = isset($route) && $route->hasOption('_auth');
|
||||
|
||||
if ($has_auth_option) {
|
||||
return in_array($provider_id, $route->getOption('_auth'));
|
||||
}
|
||||
else {
|
||||
return isset($this->globalProviders[$provider_id]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sorted array of authentication providers.
|
||||
*
|
||||
* @return \Drupal\Core\Authentication\AuthenticationProviderInterface[]
|
||||
* An array of authentication provider objects.
|
||||
*/
|
||||
protected function getSortedProviders() {
|
||||
if (!isset($this->sortedProviders)) {
|
||||
// Sort the builders according to priority.
|
||||
krsort($this->providerOrders);
|
||||
// Merge nested providers from $this->providers into $this->sortedProviders.
|
||||
$this->sortedProviders = array();
|
||||
foreach ($this->providerOrders as $providers) {
|
||||
$this->sortedProviders = array_merge($this->sortedProviders, $providers);
|
||||
}
|
||||
}
|
||||
return $this->sortedProviders;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Authentication\AuthenticationManagerInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Authentication;
|
||||
|
||||
/**
|
||||
* Defines an interface for authentication managers.
|
||||
*/
|
||||
interface AuthenticationManagerInterface {
|
||||
|
||||
/**
|
||||
* Adds a provider to the array of registered providers.
|
||||
*
|
||||
* @param \Drupal\Core\Authentication\AuthenticationProviderInterface $provider
|
||||
* The provider object.
|
||||
* @param string $provider_id
|
||||
* Identifier of the provider.
|
||||
* @param int $priority
|
||||
* (optional) The provider's priority.
|
||||
* @param bool $global
|
||||
* (optional) TRUE if the provider is to be applied globally on all routes.
|
||||
* Defaults to FALSE.
|
||||
*/
|
||||
public function addProvider(AuthenticationProviderInterface $provider, $provider_id, $priority = 0, $global = FALSE);
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Authentication\AuthenticationProviderChallengeInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Authentication;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Generate a challenge when access is denied for unauthenticated users.
|
||||
*
|
||||
* On a 403 (access denied), if there are no credentials on the request, some
|
||||
* authentication methods (e.g. basic auth) require that a challenge is sent to
|
||||
* the client.
|
||||
*/
|
||||
interface AuthenticationProviderChallengeInterface {
|
||||
|
||||
/**
|
||||
* Constructs an exception which is used to generate the challenge.
|
||||
*
|
||||
* @var \Symfony\Component\HttpFoundation\Request
|
||||
* The request.
|
||||
* @var \Exception $exception
|
||||
* The previous exception.
|
||||
*
|
||||
* @return \Symfony\Component\HttpKernel\Exception\HttpExceptionInterface|NULL
|
||||
* An exception to be used in order to generate an authentication challenge.
|
||||
*/
|
||||
public function challengeException(Request $request, \Exception $previous);
|
||||
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Authentication\AuthenticationProviderFilterInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Authentication;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Restrict authentication methods to a subset of the site.
|
||||
*
|
||||
* Some authentication methods should not be available throughout a whole site.
|
||||
* E.g., there are good reasons to restrict insecure methods like HTTP basic
|
||||
* auth or an URL token authentication method to API-only routes.
|
||||
*/
|
||||
interface AuthenticationProviderFilterInterface {
|
||||
|
||||
/**
|
||||
* Checks whether the authentication method is allowed on a given route.
|
||||
*
|
||||
* While authentication itself is run before routing, this method is called
|
||||
* after routing, hence RouteMatch is available and can be used to inspect
|
||||
* route options.
|
||||
*
|
||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||
* The request.
|
||||
* @param bool $authenticated
|
||||
* Whether or not the request is authenticated.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if an authentication method is allowed on the request, otherwise
|
||||
* FALSE.
|
||||
*/
|
||||
public function appliesToRoutedRequest(Request $request, $authenticated);
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Authentication\AuthenticationProviderInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Authentication;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Interface for authentication providers.
|
||||
*/
|
||||
interface AuthenticationProviderInterface {
|
||||
|
||||
/**
|
||||
* Checks whether suitable authentication credentials are on the request.
|
||||
*
|
||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||
* The request object.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if authentication credentials suitable for this provider are on the
|
||||
* request, FALSE otherwise.
|
||||
*/
|
||||
public function applies(Request $request);
|
||||
|
||||
/**
|
||||
* Authenticates the user.
|
||||
*
|
||||
* @param \Symfony\Component\HttpFoundation\Request|NULL $request
|
||||
* The request object.
|
||||
*
|
||||
* @return \Drupal\Core\Session\AccountInterface|NULL
|
||||
* AccountInterface - in case of a successful authentication.
|
||||
* NULL - in case where authentication failed.
|
||||
*/
|
||||
public function authenticate(Request $request);
|
||||
|
||||
}
|
Reference in a new issue