You are here

public function UsersJwtAuth::authenticate in JSON Web Token Authentication (JWT) 8

Authenticates the user.

Parameters

\Symfony\Component\HttpFoundation\Request|null $request: The request object.

Return value

\Drupal\Core\Session\AccountInterface|null AccountInterface - in case of a successful authentication. NULL - in case where authentication failed.

Overrides AuthenticationProviderInterface::authenticate

File

modules/users_jwt/src/Authentication/Provider/UsersJwtAuth.php, line 86

Class

UsersJwtAuth
Class UsersJwtAuth.

Namespace

Drupal\users_jwt\Authentication\Provider

Code

public function authenticate(Request $request) {
  $raw_jwt = self::getJwtFromRequest($request);
  try {

    // @todo add Ed25519 here as allowed when it's supported. We verify the
    // algorithm from the key matches the header below so we can allow
    // multiple here.
    $payload = JWT::decode($raw_jwt, $this->keyRepository, [
      'RS256',
    ]);
  } catch (\Exception $e) {
    return $this
      ->debugLog('JWT decode exception', $e);
  }

  // This approach requires the these two reserved claims. This prevents users
  // from issuing long-lived tokens that could be abused while not going as
  // far as requiring a unique JWT per request.
  // @todo provide a config for maximum token lifetime.
  if (!isset($payload->iat, $payload->exp) || $payload->exp - $payload->iat > 24 * 3600) {
    return $this
      ->debugLog('Bad iat, exp claims', NULL, $payload);
  }

  // Unfortunately this JWT implementation does not save or allow the
  // header to be retrieved via a simple method, so we need to decode it
  // again. The decode call above has already validated it.
  $tks = explode('.', $raw_jwt);
  $headb64 = $tks[0];
  $header = JWT::jsonDecode(JWT::urlsafeB64Decode($headb64));
  $key = $this->keyRepository
    ->getKey($header->kid);
  if ($header->alg !== $key->alg) {
    return $this
      ->debugLog('Bad header alg', NULL, $payload, $key);
  }
  if (empty($payload->drupal->uid) || (int) $payload->drupal->uid !== $key->uid) {
    return $this
      ->debugLog('Bad uid claim', NULL, $payload, $key);
  }

  /** @var \Drupal\user\UserInterface $user */
  $user = $this->entityTypeManager
    ->getStorage('user')
    ->load($key->uid);
  if ($user && !$user
    ->isBlocked()) {
    return $user;
  }
  return $this
    ->debugLog('Bad user', NULL, $payload, $key, $user);
}