You are here

public function OpenIDConnectRedirectController::authenticate in OpenID Connect / OAuth client 2.x

Same name and namespace in other branches
  1. 8 src/Controller/OpenIDConnectRedirectController.php \Drupal\openid_connect\Controller\OpenIDConnectRedirectController::authenticate()

Redirect.

Parameters

\Drupal\openid_connect\OpenIDConnectClientEntityInterface $openid_connect_client: The client.

Return value

\Symfony\Component\HttpFoundation\RedirectResponse The redirect response starting the authentication request.

Throws

\Exception

1 string reference to 'OpenIDConnectRedirectController::authenticate'
openid_connect.routing.yml in ./openid_connect.routing.yml
openid_connect.routing.yml

File

src/Controller/OpenIDConnectRedirectController.php, line 195

Class

OpenIDConnectRedirectController
Redirect controller.

Namespace

Drupal\openid_connect\Controller

Code

public function authenticate(OpenIDConnectClientEntityInterface $openid_connect_client) : RedirectResponse {
  $request = $this->requestStack
    ->getCurrentRequest();

  // Delete the state token, since it's already been confirmed.
  $this->session
    ->retrieveStateToken();

  // Get parameters from the session, and then clean up.
  $params = $this->session
    ->retrieveOp();
  $op = $params['op'] ?? 'login';
  $uid = $params['uid'] ?? NULL;
  $plugin = $openid_connect_client
    ->getPlugin();
  if (!$request
    ->get('error') && (!$plugin 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' => $openid_connect_client
      ->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
        ->getLogger('openid_connect_' . $openid_connect_client
        ->getPluginId())
        ->error($message, $variables);
      $this
        ->messenger()
        ->addError($this
        ->t('Could not authenticate with @provider.', $provider_param));
    }
  }
  else {

    // Process the login or connect operations.
    $tokens = $plugin
      ->retrieveTokens($request
      ->get('code'));
    if ($tokens) {
      if ($op === 'login') {
        $success = $this->openIDConnect
          ->completeAuthorization($openid_connect_client, $tokens);
        if (!$success) {
          $this
            ->messenger()
            ->addError($this
            ->t('Logging in with @provider could not be completed due to an error.', $provider_param));
        }
      }
      elseif ($op === 'connect' && $uid === (int) $this->currentUser
        ->id()) {
        $success = $this->openIDConnect
          ->connectCurrentUser($openid_connect_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));
    }
  }

  // The destination parameter should be a prepared uri and include any query
  // parameters or fragments already.
  //
  // @see \Drupal\openid_connect\OpenIDConnectSession::saveDestination()
  $session = $this->session
    ->retrieveDestination();
  $destination = $session['destination'] ?: $this->configFactory
    ->get('openid_connect.settings')
    ->get('redirect_login');
  $langcode = $session['langcode'] ?: $this->languageManager
    ->getCurrentLanguage()
    ->getId();
  $language = $this->languageManager
    ->getLanguage($langcode);
  $redirect = Url::fromUri('internal:/' . ltrim($destination, '/'), [
    'language' => $language,
  ])
    ->toString();
  return new RedirectResponse($redirect);
}