You are here

public function AuthController::callback in Auth0 Single Sign On 8

Same name and namespace in other branches
  1. 8.2 src/Controller/AuthController.php \Drupal\auth0\Controller\AuthController::callback()

Handles the callback for the oauth transaction.

1 string reference to 'AuthController::callback'
auth0.routing.yml in ./auth0.routing.yml
auth0.routing.yml

File

src/Controller/AuthController.php, line 188

Class

AuthController
Controller routines for auth0 authentication.

Namespace

Drupal\auth0\Controller

Code

public function callback(Request $request) {
  global $base_root;
  $config = \Drupal::service('config.factory')
    ->get('auth0.settings');

  /* Check for errors */

  // Check in query
  if ($request->query
    ->has('error') && $request->query
    ->get('error') == 'login_required') {
    return new TrustedRedirectResponse($this
      ->buildAuthorizeUrl(FALSE));
  }

  // Check in post
  if ($request->request
    ->has('error') && $request->request
    ->get('error') == 'login_required') {
    return new TrustedRedirectResponse($this
      ->buildAuthorizeUrl(FALSE));
  }
  $this->auth0 = new Auth0(array(
    'domain' => $config
      ->get('auth0_domain'),
    'client_id' => $config
      ->get('auth0_client_id'),
    'client_secret' => $config
      ->get('auth0_client_secret'),
    'redirect_uri' => "{$base_root}/auth0/callback",
    'store' => NULL,
    // Set to null so that the store is set to SessionStore.
    'persist_id_token' => FALSE,
    'persist_user' => FALSE,
    'persist_access_token' => FALSE,
    'persist_refresh_token' => FALSE,
  ));
  $userInfo = NULL;

  /**
   * Exchange the code for the tokens (happens behind the scenes in the SDK)
   */
  try {
    $userInfo = $this->auth0
      ->getUser();
    $idToken = $this->auth0
      ->getIdToken();
  } catch (\Exception $e) {
    return $this
      ->failLogin(t('There was a problem logging you in, sorry for the inconvenience.'), 'Failed to exchange code for tokens: ' . $e
      ->getMessage());
  }

  /**
   * Validate the ID Token
   */
  $auth0_domain = 'https://' . $this->domain . '/';
  $auth0_settings = array();
  $auth0_settings['authorized_iss'] = [
    $auth0_domain,
  ];
  $auth0_settings['supported_algs'] = [
    $this->auth0_jwt_signature_alg,
  ];
  $auth0_settings['valid_audiences'] = [
    $this->client_id,
  ];
  $auth0_settings['client_secret'] = $this->client_secret;
  $auth0_settings['secret_base64_encoded'] = $this->secret_base64_encoded;
  $jwt_verifier = new JWTVerifier($auth0_settings);
  try {
    $user = $jwt_verifier
      ->verifyAndDecode($idToken);
  } catch (\Exception $e) {
    return $this
      ->failLogin(t('There was a problem logging you in, sorry for the inconvenience.'), 'Failed to verify and decode the JWT: ' . $e
      ->getMessage());
  }

  /**
   * Validate the state if we redirected for login
   */
  $state = 'invalid';
  if ($request->query
    ->has('state')) {
    $state = $request->query
      ->get('state');
  }
  elseif ($request->request
    ->has('state')) {
    $state = $request->request
      ->get('state');
  }
  if (!$this
    ->compareNonce($state)) {
    return $this
      ->failLogin(t('There was a problem logging you in, sorry for the inconvenience.'), "Failed to verify the state ({$state})");
  }

  /**
   * Check the sub if it exists (this will exist if you have enabled OIDC Conformant)
   */
  if ($userInfo['sub'] != $user->sub) {
    return $this
      ->failLogin(t('There was a problem logging you in, sorry for the inconvenience.'), 'Failed to verify the JWT sub.');
  }
  elseif (array_key_exists('sub', $userInfo)) {
    $userInfo['user_id'] = $userInfo['sub'];
  }
  if ($userInfo) {
    return $this
      ->processUserLogin($request, $userInfo, $idToken);
  }
  else {
    return $this
      ->failLogin(t('There was a problem logging you in, sorry for the inconvenience.'), 'No userInfo found');
  }
}