Passport: oauth2-server now throws an uncaught exception on incorrect credentials

Created on 10 Nov 2019  ·  9Comments  ·  Source: laravel/passport

  • Passport Version: 8.0.0
  • Laravel Version: 6.5.0
  • PHP Version: 7.3.11
  • Database Driver & Version: Mysql 8.0.16

Description:

The league/oauth2-server 8.0 upgrade now throws 400 Bad Request instead of the previous 401 Unauthorized.

This is currently not handled gracefully in Passport and bubbles up to bug reporting.

@driesvints is this by design, and if so how/where should we catch the error?

Steps To Reproduce:

  • try to get a bearer token with incorrect login details

Stacktrace

Caused by: League\OAuth2\Server\Exception\OAuthServerException The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client. 
    /src/vendor/league/oauth2-server/src/Exception/OAuthServerException.php:263 League\OAuth2\Server\Exception\OAuthServerException::invalidGrant
    /src/vendor/league/oauth2-server/src/Grant/PasswordGrant.php:107 League\OAuth2\Server\Grant\PasswordGrant::validateUser
    /src/vendor/league/oauth2-server/src/Grant/PasswordGrant.php:54 League\OAuth2\Server\Grant\PasswordGrant::respondToAccessTokenRequest
    /src/vendor/league/oauth2-server/src/AuthorizationServer.php:198 League\OAuth2\Server\AuthorizationServer::respondToAccessTokenRequest
    /src/vendor/laravel/passport/src/Http/Controllers/AccessTokenController.php:63 Laravel\Passport\Http\Controllers\AccessTokenController::Laravel\Passport\Http\Controllers\{closure}
    /src/vendor/laravel/passport/src/Http/Controllers/HandlesOAuthErrors.php:24 Laravel\Passport\Http\Controllers\AccessTokenController::withErrorHandling
    /src/vendor/laravel/passport/src/Http/Controllers/AccessTokenController.php:65 Laravel\Passport\Http\Controllers\AccessTokenController::issueToken
    /src/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php:48 Illuminate\Routing\ControllerDispatcher::dispatch
    /src/vendor/laravel/framework/src/Illuminate/Routing/Route.php:219 Illuminate\Routing\Route::runController
    /src/vendor/laravel/framework/src/Illuminate/Routing/Route.php:176 Illuminate\Routing\Route::run
    /src/vendor/laravel/framework/src/Illuminate/Routing/Router.php:680 Illuminate\Routing\Router::Illuminate\Routing\{closure}
    /src/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:130 Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
    Http/Middleware/ThrottleRequests.php:23 App\Http\Middleware\ThrottleRequests::handle
    /src/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:171 Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
    /src/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:105 Illuminate\Pipeline\Pipeline::then
    /src/vendor/laravel/framework/src/Illuminate/Routing/Router.php:682 Illuminate\Routing\Router::runRouteWithinStack
    /src/vendor/laravel/framework/src/Illuminate/Routing/Router.php:657 Illuminate\Routing\Router::runRoute
    /src/vendor/laravel/framework/src/Illuminate/Routing/Router.php:623 Illuminate\Routing\Router::dispatchToRoute
    /src/vendor/laravel/framework/src/Illuminate/Routing/Router.php:612 Illuminate\Routing\Router::dispatch
    /src/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:176 Illuminate\Foundation\Http\Kernel::Illuminate\Foundation\Http\{closure}
    /src/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:130 Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
    /src/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php:21 Illuminate\Foundation\Http\Middleware\TransformsRequest::handle
    /src/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:171 Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
    /src/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php:27 Illuminate\Foundation\Http\Middleware\ValidatePostSize::handle
    /src/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:171 Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
    /src/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php:62 Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::handle
    /src/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:171 Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
    /src/vendor/fideloper/proxy/src/TrustProxies.php:57 Fideloper\Proxy\TrustProxies::handle
    /src/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:171 Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
    /src/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:105 Illuminate\Pipeline\Pipeline::then
    /src/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:151 Illuminate\Foundation\Http\Kernel::sendRequestThroughRouter
    /src/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:116 Illuminate\Foundation\Http\Kernel::handle
    /src/public/index.php:55 [main]
bug

Most helpful comment

A bit late to the party, but for other people ending up with this same issue, what I ended up doing is overriding Passport's AccessTokenController@issueToken, catching Passport's OAuthServerException and checking for the status code to match the invalid_grant exception (code 10), which only seems to be used in case of invalid credentials.
See https://github.com/thephpleague/oauth2-server/blob/master/src/Grant/PasswordGrant.php#L107 and https://github.com/thephpleague/oauth2-server/blob/master/src/Exception/OAuthServerException.php#L261 (for exception definition).

The code roughly looks like this:

use Laravel\Passport\Exceptions\OAuthServerException;
use Nyholm\Psr7\Response as Psr7Response;
use Psr\Http\Message\ServerRequestInterface;

public function issueToken(ServerRequestInterface $request)
{
    try {
        $response = $this->withErrorHandling(function () use ($request) {
            return $this->convertResponse(
                $this->server->respondToAccessTokenRequest($request, new Psr7Response)
            );
        });
    } catch (OAuthServerException $e) {
        // Invalid grant exception, only thrown in case of wrong credentials,
        // See https://github.com/thephpleague/oauth2-server/blob/master/src/Grant/PasswordGrant.php#L107
        if ($e->getCode() === 10) {
            return response()->json([
                'errors' => [__('auth.failed')],
                'message' => __('auth.failed'),
            ], 401);
        }

        throw $e;
    }

    return $response;
}

Hope this helps someone with the same issue :)

All 9 comments

Hmm, I don't see that change in the changelog here: https://github.com/thephpleague/oauth2-server/blob/master/CHANGELOG.md

@sephster do you maybe know?

Hi @driesvints - I think it might be this change:

Password Grant now returns an invalid_grant error instead of invalid_credentials if a user cannot be validated (PR #967)

It was modified to match the OAuth2 Spec. We previously returned a 401 but this was not correct.

PR is here https://github.com/thephpleague/oauth2-server/pull/967

@Sephster thanks! Looks like we need to convert the exception somewhere with the HandlesOAuthErrors trait.

@patrickomeara can you let me know what is exactly needed to reproduce this? Please share some code.

@driesvints This repo will log the error when running the curl command in the README

https://github.com/patrickomeara/passport_error

@patrickomeara I get a proper response back from the API when I test with the exact steps you've provided in the readme:

$ curl --request POST --header 'accept: application/json' --header 'content-type: application/json' --data '{"username":"[email protected]","password":"ZCP7kT","grant_type":"password","client_id":2,"client_secret":"<secret>","scope":"*","device_uuid":"B11D89CD-2208-4893-DAEB-1545C3351858"}' 'https://passport-test.test/oauth/token'

{"error":"invalid_client","error_description":"Client authentication failed","message":"Client authentication failed"}

Stacktrace

[2019-11-12 12:00:13] local.ERROR: Client authentication failed {"exception":"[object] (Laravel\\Passport\\Exceptions\\OAuthServerException(code: 4): Client authentication failed at /Users/driesvints/Sites/passport-test/vendor/laravel/passport/src/Http/Controllers/HandlesOAuthErrors.php:26)
[stacktrace]
#0 /Users/driesvints/Sites/passport-test/vendor/laravel/passport/src/Http/Controllers/AccessTokenController.php(65): Laravel\\Passport\\Http\\Controllers\\AccessTokenController->withErrorHandling(Object(Closure))
#1 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(48): Laravel\\Passport\\Http\\Controllers\\AccessTokenController->issueToken(Object(Zend\\Diactoros\\ServerRequest))
#2 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/Route.php(219): Illuminate\\Routing\\ControllerDispatcher->dispatch(Object(Illuminate\\Routing\\Route), Object(Laravel\\Passport\\Http\\Controllers\\AccessTokenController), 'issueToken')
#3 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/Route.php(176): Illuminate\\Routing\\Route->runController()
#4 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/Router.php(680): Illuminate\\Routing\\Route->run()
#5 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(130): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#6 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php(59): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#7 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Illuminate\\Routing\\Middleware\\ThrottleRequests->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#8 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(105): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#9 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/Router.php(682): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#10 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/Router.php(657): Illuminate\\Routing\\Router->runRouteWithinStack(Object(Illuminate\\Routing\\Route), Object(Illuminate\\Http\\Request))
#11 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/Router.php(623): Illuminate\\Routing\\Router->runRoute(Object(Illuminate\\Http\\Request), Object(Illuminate\\Routing\\Route))
#12 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/Router.php(612): Illuminate\\Routing\\Router->dispatchToRoute(Object(Illuminate\\Http\\Request))
#13 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(176): Illuminate\\Routing\\Router->dispatch(Object(Illuminate\\Http\\Request))
#14 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(130): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}(Object(Illuminate\\Http\\Request))
#15 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#16 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#17 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#18 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#19 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#20 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#21 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php(62): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#22 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#23 /Users/driesvints/Sites/passport-test/vendor/fideloper/proxy/src/TrustProxies.php(57): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#24 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Fideloper\\Proxy\\TrustProxies->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#25 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(105): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#26 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(151): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#27 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(116): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter(Object(Illuminate\\Http\\Request))
#28 /Users/driesvints/Sites/passport-test/public/index.php(55): Illuminate\\Foundation\\Http\\Kernel->handle(Object(Illuminate\\Http\\Request))
#29 /Users/driesvints/.composer/vendor/laravel/valet/server.php(158): require('/Users/driesvin...')
#30 {main}

[previous exception] [object] (League\\OAuth2\\Server\\Exception\\OAuthServerException(code: 4): Client authentication failed at /Users/driesvints/Sites/passport-test/vendor/league/oauth2-server/src/Exception/OAuthServerException.php:154)
[stacktrace]
#0 /Users/driesvints/Sites/passport-test/vendor/league/oauth2-server/src/Grant/AbstractGrant.php(185): League\\OAuth2\\Server\\Exception\\OAuthServerException::invalidClient(Object(Zend\\Diactoros\\ServerRequest))
#1 /Users/driesvints/Sites/passport-test/vendor/league/oauth2-server/src/Grant/PasswordGrant.php(52): League\\OAuth2\\Server\\Grant\\AbstractGrant->validateClient(Object(Zend\\Diactoros\\ServerRequest))
#2 /Users/driesvints/Sites/passport-test/vendor/league/oauth2-server/src/AuthorizationServer.php(198): League\\OAuth2\\Server\\Grant\\PasswordGrant->respondToAccessTokenRequest(Object(Zend\\Diactoros\\ServerRequest), Object(League\\OAuth2\\Server\\ResponseTypes\\BearerTokenResponse), Object(DateInterval))
#3 /Users/driesvints/Sites/passport-test/vendor/laravel/passport/src/Http/Controllers/AccessTokenController.php(63): League\\OAuth2\\Server\\AuthorizationServer->respondToAccessTokenRequest(Object(Zend\\Diactoros\\ServerRequest), Object(Zend\\Diactoros\\Response))
#4 /Users/driesvints/Sites/passport-test/vendor/laravel/passport/src/Http/Controllers/HandlesOAuthErrors.php(24): Laravel\\Passport\\Http\\Controllers\\AccessTokenController->Laravel\\Passport\\Http\\Controllers\\{closure}()
#5 /Users/driesvints/Sites/passport-test/vendor/laravel/passport/src/Http/Controllers/AccessTokenController.php(65): Laravel\\Passport\\Http\\Controllers\\AccessTokenController->withErrorHandling(Object(Closure))
#6 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(48): Laravel\\Passport\\Http\\Controllers\\AccessTokenController->issueToken(Object(Zend\\Diactoros\\ServerRequest))
#7 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/Route.php(219): Illuminate\\Routing\\ControllerDispatcher->dispatch(Object(Illuminate\\Routing\\Route), Object(Laravel\\Passport\\Http\\Controllers\\AccessTokenController), 'issueToken')
#8 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/Route.php(176): Illuminate\\Routing\\Route->runController()
#9 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/Router.php(680): Illuminate\\Routing\\Route->run()
#10 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(130): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#11 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php(59): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#12 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Illuminate\\Routing\\Middleware\\ThrottleRequests->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#13 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(105): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#14 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/Router.php(682): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#15 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/Router.php(657): Illuminate\\Routing\\Router->runRouteWithinStack(Object(Illuminate\\Routing\\Route), Object(Illuminate\\Http\\Request))
#16 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/Router.php(623): Illuminate\\Routing\\Router->runRoute(Object(Illuminate\\Http\\Request), Object(Illuminate\\Routing\\Route))
#17 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/Router.php(612): Illuminate\\Routing\\Router->dispatchToRoute(Object(Illuminate\\Http\\Request))
#18 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(176): Illuminate\\Routing\\Router->dispatch(Object(Illuminate\\Http\\Request))
#19 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(130): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}(Object(Illuminate\\Http\\Request))
#20 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#21 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#22 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#23 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#24 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#25 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#26 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php(62): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#27 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#28 /Users/driesvints/Sites/passport-test/vendor/fideloper/proxy/src/TrustProxies.php(57): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#29 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Fideloper\\Proxy\\TrustProxies->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#30 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(105): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#31 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(151): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#32 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(116): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter(Object(Illuminate\\Http\\Request))
#33 /Users/driesvints/Sites/passport-test/public/index.php(55): Illuminate\\Foundation\\Http\\Kernel->handle(Object(Illuminate\\Http\\Request))
#34 /Users/driesvints/.composer/vendor/laravel/valet/server.php(158): require('/Users/driesvin...')
#35 {main}
"} 
[2019-11-12 12:00:29] local.ERROR: Client authentication failed {"exception":"[object] (Laravel\\Passport\\Exceptions\\OAuthServerException(code: 4): Client authentication failed at /Users/driesvints/Sites/passport-test/vendor/laravel/passport/src/Http/Controllers/HandlesOAuthErrors.php:26)
[stacktrace]
#0 /Users/driesvints/Sites/passport-test/vendor/laravel/passport/src/Http/Controllers/AccessTokenController.php(65): Laravel\\Passport\\Http\\Controllers\\AccessTokenController->withErrorHandling(Object(Closure))
#1 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(48): Laravel\\Passport\\Http\\Controllers\\AccessTokenController->issueToken(Object(Zend\\Diactoros\\ServerRequest))
#2 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/Route.php(219): Illuminate\\Routing\\ControllerDispatcher->dispatch(Object(Illuminate\\Routing\\Route), Object(Laravel\\Passport\\Http\\Controllers\\AccessTokenController), 'issueToken')
#3 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/Route.php(176): Illuminate\\Routing\\Route->runController()
#4 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/Router.php(680): Illuminate\\Routing\\Route->run()
#5 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(130): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#6 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php(59): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#7 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Illuminate\\Routing\\Middleware\\ThrottleRequests->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#8 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(105): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#9 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/Router.php(682): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#10 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/Router.php(657): Illuminate\\Routing\\Router->runRouteWithinStack(Object(Illuminate\\Routing\\Route), Object(Illuminate\\Http\\Request))
#11 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/Router.php(623): Illuminate\\Routing\\Router->runRoute(Object(Illuminate\\Http\\Request), Object(Illuminate\\Routing\\Route))
#12 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/Router.php(612): Illuminate\\Routing\\Router->dispatchToRoute(Object(Illuminate\\Http\\Request))
#13 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(176): Illuminate\\Routing\\Router->dispatch(Object(Illuminate\\Http\\Request))
#14 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(130): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}(Object(Illuminate\\Http\\Request))
#15 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#16 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#17 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#18 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#19 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#20 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#21 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php(62): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#22 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#23 /Users/driesvints/Sites/passport-test/vendor/fideloper/proxy/src/TrustProxies.php(57): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#24 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Fideloper\\Proxy\\TrustProxies->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#25 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(105): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#26 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(151): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#27 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(116): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter(Object(Illuminate\\Http\\Request))
#28 /Users/driesvints/Sites/passport-test/public/index.php(55): Illuminate\\Foundation\\Http\\Kernel->handle(Object(Illuminate\\Http\\Request))
#29 /Users/driesvints/.composer/vendor/laravel/valet/server.php(158): require('/Users/driesvin...')
#30 {main}

[previous exception] [object] (League\\OAuth2\\Server\\Exception\\OAuthServerException(code: 4): Client authentication failed at /Users/driesvints/Sites/passport-test/vendor/league/oauth2-server/src/Exception/OAuthServerException.php:154)
[stacktrace]
#0 /Users/driesvints/Sites/passport-test/vendor/league/oauth2-server/src/Grant/AbstractGrant.php(185): League\\OAuth2\\Server\\Exception\\OAuthServerException::invalidClient(Object(Zend\\Diactoros\\ServerRequest))
#1 /Users/driesvints/Sites/passport-test/vendor/league/oauth2-server/src/Grant/PasswordGrant.php(52): League\\OAuth2\\Server\\Grant\\AbstractGrant->validateClient(Object(Zend\\Diactoros\\ServerRequest))
#2 /Users/driesvints/Sites/passport-test/vendor/league/oauth2-server/src/AuthorizationServer.php(198): League\\OAuth2\\Server\\Grant\\PasswordGrant->respondToAccessTokenRequest(Object(Zend\\Diactoros\\ServerRequest), Object(League\\OAuth2\\Server\\ResponseTypes\\BearerTokenResponse), Object(DateInterval))
#3 /Users/driesvints/Sites/passport-test/vendor/laravel/passport/src/Http/Controllers/AccessTokenController.php(63): League\\OAuth2\\Server\\AuthorizationServer->respondToAccessTokenRequest(Object(Zend\\Diactoros\\ServerRequest), Object(Zend\\Diactoros\\Response))
#4 /Users/driesvints/Sites/passport-test/vendor/laravel/passport/src/Http/Controllers/HandlesOAuthErrors.php(24): Laravel\\Passport\\Http\\Controllers\\AccessTokenController->Laravel\\Passport\\Http\\Controllers\\{closure}()
#5 /Users/driesvints/Sites/passport-test/vendor/laravel/passport/src/Http/Controllers/AccessTokenController.php(65): Laravel\\Passport\\Http\\Controllers\\AccessTokenController->withErrorHandling(Object(Closure))
#6 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(48): Laravel\\Passport\\Http\\Controllers\\AccessTokenController->issueToken(Object(Zend\\Diactoros\\ServerRequest))
#7 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/Route.php(219): Illuminate\\Routing\\ControllerDispatcher->dispatch(Object(Illuminate\\Routing\\Route), Object(Laravel\\Passport\\Http\\Controllers\\AccessTokenController), 'issueToken')
#8 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/Route.php(176): Illuminate\\Routing\\Route->runController()
#9 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/Router.php(680): Illuminate\\Routing\\Route->run()
#10 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(130): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#11 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php(59): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#12 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Illuminate\\Routing\\Middleware\\ThrottleRequests->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#13 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(105): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#14 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/Router.php(682): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#15 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/Router.php(657): Illuminate\\Routing\\Router->runRouteWithinStack(Object(Illuminate\\Routing\\Route), Object(Illuminate\\Http\\Request))
#16 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/Router.php(623): Illuminate\\Routing\\Router->runRoute(Object(Illuminate\\Http\\Request), Object(Illuminate\\Routing\\Route))
#17 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Routing/Router.php(612): Illuminate\\Routing\\Router->dispatchToRoute(Object(Illuminate\\Http\\Request))
#18 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(176): Illuminate\\Routing\\Router->dispatch(Object(Illuminate\\Http\\Request))
#19 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(130): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}(Object(Illuminate\\Http\\Request))
#20 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#21 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#22 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#23 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#24 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#25 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#26 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php(62): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#27 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#28 /Users/driesvints/Sites/passport-test/vendor/fideloper/proxy/src/TrustProxies.php(57): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#29 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Fideloper\\Proxy\\TrustProxies->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#30 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(105): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#31 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(151): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#32 /Users/driesvints/Sites/passport-test/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(116): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter(Object(Illuminate\\Http\\Request))
#33 /Users/driesvints/Sites/passport-test/public/index.php(55): Illuminate\\Foundation\\Http\\Kernel->handle(Object(Illuminate\\Http\\Request))
#34 /Users/driesvints/.composer/vendor/laravel/valet/server.php(158): require('/Users/driesvin...')
#35 {main}
"} 

So this leads me to believe you might have some missing dependencies or there might be something else we're missing.

Can you first please try one of the support channels below? If you can actually identify this as a bug, feel free to report back and I'll gladly help you out and re-open this issue.

Thanks!

@driesvints yep, I get the same response back. But since the upgrade we are now notified of incorrect logins through bugsnag, whereas previously incorrect logins were handled gracefully.

This could be something we ignore through bugsnag, but that feels like an extra step for passport users.

I’ll keep an eye on this, I’m sure others will have similar issues. It seems like a common setup.

@patrickomeara okay. Since @Sephster indicated that this change happened to conform more to the OAuth spec and it was indicated in the changelog of their library I'm gonna leave it as this. Thanks for making use aware though 👍

A bit late to the party, but for other people ending up with this same issue, what I ended up doing is overriding Passport's AccessTokenController@issueToken, catching Passport's OAuthServerException and checking for the status code to match the invalid_grant exception (code 10), which only seems to be used in case of invalid credentials.
See https://github.com/thephpleague/oauth2-server/blob/master/src/Grant/PasswordGrant.php#L107 and https://github.com/thephpleague/oauth2-server/blob/master/src/Exception/OAuthServerException.php#L261 (for exception definition).

The code roughly looks like this:

use Laravel\Passport\Exceptions\OAuthServerException;
use Nyholm\Psr7\Response as Psr7Response;
use Psr\Http\Message\ServerRequestInterface;

public function issueToken(ServerRequestInterface $request)
{
    try {
        $response = $this->withErrorHandling(function () use ($request) {
            return $this->convertResponse(
                $this->server->respondToAccessTokenRequest($request, new Psr7Response)
            );
        });
    } catch (OAuthServerException $e) {
        // Invalid grant exception, only thrown in case of wrong credentials,
        // See https://github.com/thephpleague/oauth2-server/blob/master/src/Grant/PasswordGrant.php#L107
        if ($e->getCode() === 10) {
            return response()->json([
                'errors' => [__('auth.failed')],
                'message' => __('auth.failed'),
            ], 401);
        }

        throw $e;
    }

    return $response;
}

Hope this helps someone with the same issue :)

Any chance this can be reopened and the solution presented by @thtg88 could be put into the Passport base? This seems a bit hacky for something that, in my opinion, should be the default behavior an API client would expect.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

huiyonghkw picture huiyonghkw  ·  3Comments

soubhikchatterjee picture soubhikchatterjee  ·  4Comments

cookiejarblush picture cookiejarblush  ·  4Comments

parth-vora-7 picture parth-vora-7  ·  4Comments

SwiTool picture SwiTool  ·  3Comments