- Issue created by @mcgettrs
- @mcgettrs opened merge request.
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}
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.
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);
Active
5.2
Code