TypeError: in TokenAuthUser::__construct(): Argument #1 ($token) should be Oauth2TokenInterface, bool given

Created on 16 March 2023, almost 2 years ago

Problem/Motivation

I have noticed a php error in the logs of a site I work wherein TokenAuthUser is given a bool instead of a token in the SimpleOauthAuthenticationProvider. This returns a 500 error on the api endpoint I am using with oauth.

The error and stack trace are as follows:

TypeError: Drupal\simple_oauth\Authentication\TokenAuthUser::__construct(): Argument #1 ($token) must be of type Drupal\simple_oauth\Entity\Oauth2TokenInterface, bool given, called in /var/www/html/web/modules/contrib/simple_oauth/src/Authentication/Provider/SimpleOauthAuthenticationProvider.php on line 95 in Drupal\simple_oauth\Authentication\TokenAuthUser->__construct() (line 51 of /var/www/html/web/modules/contrib/simple_oauth/src/Authentication/TokenAuthUser.php)
#0 /var/www/html/web/modules/contrib/simple_oauth/src/Authentication/Provider/SimpleOauthAuthenticationProvider.php(95): Drupal\simple_oauth\Authentication\TokenAuthUser->__construct(false)
#1 /var/www/html/web/core/lib/Drupal/Core/Authentication/AuthenticationManager.php(52): Drupal\simple_oauth\Authentication\Provider\SimpleOauthAuthenticationProvider->authenticate(Object(Symfony\Component\HttpFoundation\Request))
#2 /var/www/html/web/core/lib/Drupal/Core/EventSubscriber/AuthenticationSubscriber.php(77): Drupal\Core\Authentication\AuthenticationManager->authenticate(Object(Symfony\Component\HttpFoundation\Request))
#3 [internal function]: Drupal\Core\EventSubscriber\AuthenticationSubscriber->onKernelRequestAuthenticate(Object(Symfony\Component\HttpKernel\Event\RequestEvent), 'kernel.request', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher))
#4 /var/www/html/web/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php(142): call_user_func(Array, Object(Symfony\Component\HttpKernel\Event\RequestEvent), 'kernel.request', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher))
#5 /var/www/html/vendor/symfony/http-kernel/HttpKernel.php(145): Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object(Symfony\Component\HttpKernel\Event\RequestEvent), 'kernel.request')
#6 /var/www/html/vendor/symfony/http-kernel/HttpKernel.php(81): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1)
#7 /var/www/html/web/modules/contrib/simple_oauth/src/HttpMiddleware/BasicAuthSwap.php(68): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#8 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/Session.php(58): Drupal\simple_oauth\HttpMiddleware\BasicAuthSwap->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#9 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(48): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#10 /var/www/html/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#11 /var/www/html/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#12 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(48): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#13 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(51): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#14 /var/www/html/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#15 /var/www/html/web/core/lib/Drupal/Core/DrupalKernel.php(713): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#16 /var/www/html/web/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request))
#17 {main}

Steps to reproduce

It is very difficult to recreate and appears to happens somewhat randomly.

Looking at the code my only thought is that the token is deleted by cron because it has just expired after the request has been verified but before the request loads the token in this step. Based on the randomness of the error messages in the log a race condition of this sort seems plausible.

Proposed resolution

Add a null check to the token variable before calling

$account = new TokenAuthUser($token);

So the code would become:

/** @var \Drupal\simple_oauth\Entity\Oauth2Token $token */
    $token = reset($tokens);
    if (!$token instanceof Oauth2TokenInterface)
    {
      // throw access denied.
    } 
    $account = new TokenAuthUser($token);
🐛 Bug report
Status

Active

Version

5.2

Component

Code

Created by

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @mcgettrs
  • @mcgettrs opened merge request.
Production build 0.71.5 2024