class OpenIDConnectRedirectController in OpenID Connect / OAuth client 8
Same name and namespace in other branches
- 2.x src/Controller/OpenIDConnectRedirectController.php \Drupal\openid_connect\Controller\OpenIDConnectRedirectController
Redirect controller.
@package Drupal\openid_connect\Controller
Hierarchy
- class \Drupal\Core\Controller\ControllerBase implements ContainerInjectionInterface uses LoggerChannelTrait, MessengerTrait, LinkGeneratorTrait, RedirectDestinationTrait, UrlGeneratorTrait, StringTranslationTrait
- class \Drupal\openid_connect\Controller\OpenIDConnectRedirectController implements AccessInterface
Expanded class hierarchy of OpenIDConnectRedirectController
File
- src/
Controller/ OpenIDConnectRedirectController.php, line 25
Namespace
Drupal\openid_connect\ControllerView source
class OpenIDConnectRedirectController extends ControllerBase implements AccessInterface {
/**
* The OpenID client plugin manager.
*
* @var \Drupal\openid_connect\Plugin\OpenIDConnectClientManager
*/
protected $pluginManager;
/**
* The OpenID state token service.
*
* @var \Drupal\openid_connect\OpenIDConnectStateTokenInterface
*/
protected $stateToken;
/**
* The request stack used to access request globals.
*
* @var \Symfony\Component\HttpFoundation\RequestStack
*/
protected $requestStack;
/**
* The logger factory.
*
* @var \Drupal\Core\Logger\LoggerChannelFactoryInterface
*/
protected $loggerFactory;
/**
* The OpenID Connect service.
*
* @var \Drupal\openid_connect\OpenIDConnect
*/
protected $openIDConnect;
/**
* The constructor.
*
* @param \Drupal\openid_connect\Plugin\OpenIDConnectClientManager $plugin_manager
* The OpenID client plugin manager.
* @param \Drupal\openid_connect\OpenIDConnect $openid_connect
* The OpenID Connect service.
* @param \Drupal\openid_connect\OpenIDConnectStateTokenInterface $state_token
* The OpenID state token service.
* @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
* The request stack.
* @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $logger_factory
* The logger factory.
*/
public function __construct(OpenIDConnectClientManager $plugin_manager, OpenIDConnect $openid_connect, OpenIDConnectStateTokenInterface $state_token, RequestStack $request_stack, LoggerChannelFactoryInterface $logger_factory) {
$this->pluginManager = $plugin_manager;
$this->openIDConnect = $openid_connect;
$this->stateToken = $state_token;
$this->requestStack = $request_stack;
$this->loggerFactory = $logger_factory;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static($container
->get('plugin.manager.openid_connect_client'), $container
->get('openid_connect.openid_connect'), $container
->get('openid_connect.state_token'), $container
->get('request_stack'), $container
->get('logger.factory'));
}
/**
* Access callback: Redirect page.
*
* @return \Drupal\Core\Access\AccessResultInterface
* Whether the state token matches the previously created one that is stored
* in the session.
*/
public function access() {
// Confirm anti-forgery state token. This round-trip verification helps to
// ensure that the user, not a malicious script, is making the request.
$request = $this->requestStack
->getCurrentRequest();
$state_token = $request
->get('state');
if ($state_token && $this->stateToken
->confirm($state_token)) {
return AccessResult::allowed();
}
return AccessResult::forbidden();
}
/**
* Redirect.
*
* @param string $client_name
* The client name.
*
* @return \Symfony\Component\HttpFoundation\RedirectResponse
* The redirect response starting the authentication request.
*/
public function authenticate($client_name) {
$request = $this->requestStack
->getCurrentRequest();
// Delete the state token, since it's already been confirmed.
unset($_SESSION['openid_connect_state']);
// Get parameters from the session, and then clean up.
$parameters = [
'destination' => 'user',
'op' => 'login',
'connect_uid' => NULL,
];
foreach ($parameters as $key => $default) {
if (isset($_SESSION['openid_connect_' . $key])) {
$parameters[$key] = $_SESSION['openid_connect_' . $key];
unset($_SESSION['openid_connect_' . $key]);
}
}
$destination = $parameters['destination'];
$configuration = $this
->config('openid_connect.settings.' . $client_name)
->get('settings');
$client = $this->pluginManager
->createInstance($client_name, $configuration);
if (!$request
->get('error') && (!$client instanceof OpenIDConnectClientInterface || !$request
->get('code'))) {
// In case we don't have an error, but the client could not be loaded or
// there is no state token specified, the URI is probably being visited
// outside of the login flow.
throw new NotFoundHttpException();
}
$provider_param = [
'@provider' => $client
->getPluginDefinition()['label'],
];
if ($request
->get('error')) {
if (in_array($request
->get('error'), [
'interaction_required',
'login_required',
'account_selection_required',
'consent_required',
])) {
// If we have an one of the above errors, that means the user hasn't
// granted the authorization for the claims.
$this
->messenger()
->addWarning($this
->t('Logging in with @provider has been canceled.', $provider_param));
}
else {
// Any other error should be logged. E.g. invalid scope.
$variables = [
'@error' => $request
->get('error'),
'@details' => $request
->get('error_description') ? $request
->get('error_description') : $this
->t('Unknown error.'),
];
$message = 'Authorization failed: @error. Details: @details';
$this->loggerFactory
->get('openid_connect_' . $client_name)
->error($message, $variables);
$this
->messenger()
->addError($this
->t('Could not authenticate with @provider.', $provider_param));
}
}
else {
// Process the login or connect operations.
$tokens = $client
->retrieveTokens($request
->get('code'));
if ($tokens) {
if ($parameters['op'] === 'login') {
$success = $this->openIDConnect
->completeAuthorization($client, $tokens, $destination);
if (!$success) {
// Check Drupal user register settings before saving.
$register = $this
->config('user.settings')
->get('register');
// Respect possible override from OpenID-Connect settings.
$register_override = $this
->config('openid_connect.settings')
->get('override_registration_settings');
if ($register === UserInterface::REGISTER_ADMINISTRATORS_ONLY && $register_override) {
$register = UserInterface::REGISTER_VISITORS;
}
switch ($register) {
case UserInterface::REGISTER_ADMINISTRATORS_ONLY:
case UserInterface::REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL:
// Skip creating an error message, as completeAuthorization
// already added according messages.
break;
default:
$this
->messenger()
->addError($this
->t('Logging in with @provider could not be completed due to an error.', $provider_param));
break;
}
}
}
elseif ($parameters['op'] === 'connect' && $parameters['connect_uid'] === $this
->currentUser()
->id()) {
$success = $this->openIDConnect
->connectCurrentUser($client, $tokens);
if ($success) {
$this
->messenger()
->addMessage($this
->t('Account successfully connected with @provider.', $provider_param));
}
else {
$this
->messenger()
->addError($this
->t('Connecting with @provider could not be completed due to an error.', $provider_param));
}
}
}
else {
$this
->messenger()
->addError($this
->t('Failed to get authentication tokens for @provider. Check logs for further details.', $provider_param));
}
}
// It's possible to set 'options' in the redirect destination.
if (is_array($destination)) {
$query = !empty($destination[1]['query']) ? '?' . $destination[1]['query'] : '';
$redirect = Url::fromUri('internal:/' . ltrim($destination[0], '/') . $query)
->toString();
}
else {
$redirect = Url::fromUri('internal:/' . ltrim($destination, '/'))
->toString();
}
return new RedirectResponse($redirect);
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
ControllerBase:: |
protected | property | The configuration factory. | |
ControllerBase:: |
protected | property | The current user service. | 1 |
ControllerBase:: |
protected | property | The entity form builder. | |
ControllerBase:: |
protected | property | The entity manager. | |
ControllerBase:: |
protected | property | The entity type manager. | |
ControllerBase:: |
protected | property | The form builder. | 2 |
ControllerBase:: |
protected | property | The key-value storage. | 1 |
ControllerBase:: |
protected | property | The language manager. | 1 |
ControllerBase:: |
protected | property | The module handler. | 2 |
ControllerBase:: |
protected | property | The state service. | |
ControllerBase:: |
protected | function | Returns the requested cache bin. | |
ControllerBase:: |
protected | function | Retrieves a configuration object. | |
ControllerBase:: |
private | function | Returns the service container. | |
ControllerBase:: |
protected | function | Returns the current user. | 1 |
ControllerBase:: |
protected | function | Retrieves the entity form builder. | |
ControllerBase:: |
protected | function | Retrieves the entity manager service. | |
ControllerBase:: |
protected | function | Retrieves the entity type manager. | |
ControllerBase:: |
protected | function | Returns the form builder service. | 2 |
ControllerBase:: |
protected | function | Returns a key/value storage collection. | 1 |
ControllerBase:: |
protected | function | Returns the language manager service. | 1 |
ControllerBase:: |
protected | function | Returns the module handler. | 2 |
ControllerBase:: |
protected | function |
Returns a redirect response object for the specified route. Overrides UrlGeneratorTrait:: |
|
ControllerBase:: |
protected | function | Returns the state storage service. | |
LinkGeneratorTrait:: |
protected | property | The link generator. | 1 |
LinkGeneratorTrait:: |
protected | function | Returns the link generator. | |
LinkGeneratorTrait:: |
protected | function | Renders a link to a route given a route name and its parameters. | |
LinkGeneratorTrait:: |
public | function | Sets the link generator service. | |
LoggerChannelTrait:: |
protected | function | Gets the logger for a specific channel. | |
LoggerChannelTrait:: |
public | function | Injects the logger channel factory. | |
MessengerTrait:: |
protected | property | The messenger. | 29 |
MessengerTrait:: |
public | function | Gets the messenger. | 29 |
MessengerTrait:: |
public | function | Sets the messenger. | |
OpenIDConnectRedirectController:: |
protected | property |
The logger factory. Overrides LoggerChannelTrait:: |
|
OpenIDConnectRedirectController:: |
protected | property | The OpenID Connect service. | |
OpenIDConnectRedirectController:: |
protected | property | The OpenID client plugin manager. | |
OpenIDConnectRedirectController:: |
protected | property | The request stack used to access request globals. | |
OpenIDConnectRedirectController:: |
protected | property | The OpenID state token service. | |
OpenIDConnectRedirectController:: |
public | function | Access callback: Redirect page. | |
OpenIDConnectRedirectController:: |
public | function | Redirect. | |
OpenIDConnectRedirectController:: |
public static | function |
Instantiates a new instance of this class. Overrides ControllerBase:: |
|
OpenIDConnectRedirectController:: |
public | function | The constructor. | |
RedirectDestinationTrait:: |
protected | property | The redirect destination service. | 1 |
RedirectDestinationTrait:: |
protected | function | Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url. | |
RedirectDestinationTrait:: |
protected | function | Returns the redirect destination service. | |
RedirectDestinationTrait:: |
public | function | Sets the redirect destination service. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. | |
UrlGeneratorTrait:: |
protected | property | The url generator. | |
UrlGeneratorTrait:: |
protected | function | Returns the URL generator service. | |
UrlGeneratorTrait:: |
public | function | Sets the URL generator service. | |
UrlGeneratorTrait:: |
protected | function | Generates a URL or path for a specific route based on the given parameters. |