Last active
March 27, 2019 18:12
-
-
Save realshadow/f01b7bc781e089a21c64f56c565e29e2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
|-------------------------------------------------------------------------- | |
| Authentication Providers | |
|-------------------------------------------------------------------------- | |
| | |
| The authentication providers that should be used when attempting to | |
| authenticate an incoming API request. | |
| | |
*/ | |
'auth' => [ | |
'oauth' => App\Auth\Providers\Dingo\PassportProvider::class, | |
], |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$this->app->make(\Dingo\Api\Auth\Auth::class)->extend('oauth', function (Application $app) { | |
$provider = new PassportProvider( | |
$app->make(ResourceServer::class), | |
$app->make(TokenRepository::class) | |
); | |
$provider->setClientResolver(function (Token $token) { | |
return $token->client_id; | |
}); | |
$provider->setUserResolver(function (Token $token) use ($app) { | |
/** @var LoginService $service */ | |
$service = $app->make(LoginService::class); | |
return $service->loginUsingPassport($token); | |
}); | |
return $provider; | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Auth\Providers\Dingo; | |
use Dingo\Api\Auth\Provider\Authorization; | |
use Dingo\Api\Routing\Route; | |
use Illuminate\Http\Request; | |
use Laravel\Passport\Passport; | |
use Laravel\Passport\Token; | |
use Laravel\Passport\TokenRepository; | |
use League\OAuth2\Server\Exception\OAuthServerException; | |
use League\OAuth2\Server\ResourceServer; | |
use Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory; | |
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException; | |
class PassportProvider extends Authorization | |
{ | |
/** | |
* @var ResourceServer $server | |
*/ | |
protected $server; | |
/** | |
* @var TokenRepository $tokenRepository | |
*/ | |
protected $tokenRepository; | |
/** | |
* @var $userResolver | |
*/ | |
protected $userResolver; | |
/** | |
* @var $clientResolver | |
*/ | |
protected $clientResolver; | |
/** | |
* Set the resolver to fetch a user. | |
* | |
* @param callable $resolver | |
* | |
* @return \Dingo\Api\Contract\Auth\Provider | |
*/ | |
public function setUserResolver(callable $resolver) | |
{ | |
$this->userResolver = $resolver; | |
return $this; | |
} | |
/** | |
* Set the resolver to fetch a client. | |
* | |
* @param callable $resolver | |
* | |
* @return \Dingo\Api\Contract\Auth\Provider | |
*/ | |
public function setClientResolver(callable $resolver) | |
{ | |
$this->clientResolver = $resolver; | |
return $this; | |
} | |
/** | |
* Validate a route has any scopes. | |
* | |
* @param Token $token | |
* @param array $scopes | |
* | |
* @return bool | |
* @throws OAuthServerException | |
*/ | |
protected function validateAnyRouteScopes(Token $token, array $scopes) | |
{ | |
if (count($scopes) === 0) { | |
return true; | |
} | |
foreach ($scopes as $scope) { | |
if ($token->can($scope)) { | |
return true; | |
} | |
} | |
throw OAuthServerException::invalidRequest('scope'); | |
} | |
/** | |
* Validate a route has all scopes | |
* | |
* @param Token $token | |
* @param array $scopes | |
* | |
* @return bool | |
* @throws OAuthServerException | |
*/ | |
protected function validateAllRouteScopes(Token $token, array $scopes) | |
{ | |
foreach ($scopes as $scope) { | |
if (! $token->can($scope)) { | |
throw OAuthServerException::invalidScope($scope); | |
} | |
} | |
return true; | |
} | |
/** | |
* Resolve the resource owner | |
* | |
* @param Token $token | |
* | |
* @return mixed | |
*/ | |
protected function resolveResourceOwner(Token $token) | |
{ | |
if ( ! $token->user_id) { | |
return call_user_func($this->clientResolver, $token); | |
} | |
return call_user_func($this->userResolver, $token); | |
} | |
/** | |
* @param ResourceServer $server | |
* @param TokenRepository $tokenRepository | |
*/ | |
public function __construct(ResourceServer $server, TokenRepository $tokenRepository) | |
{ | |
$this->server = $server; | |
$this->tokenRepository = $tokenRepository; | |
} | |
/** | |
* Get the expected authentification method | |
* | |
* @return string | |
*/ | |
public function getAuthorizationMethod() | |
{ | |
return 'bearer'; | |
} | |
/** | |
* Authenticate the request | |
* | |
* @param Request $request | |
* @param Route $route | |
* | |
* @return mixed | |
* @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException | |
* @throws \Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException | |
*/ | |
public function authenticate(Request $request, Route $route) | |
{ | |
$this->validateAuthorizationHeader($request); | |
$psr7request = (new DiactorosFactory)->createRequest($request); | |
try { | |
$oauthRequest = $this->server->validateAuthenticatedRequest($psr7request); | |
$scopes = $route->scopes(); | |
$token = $this->tokenRepository->find($oauthRequest->getAttribute('oauth_access_token_id')); | |
if ($token->revoked) { | |
throw OAuthServerException::accessDenied(); | |
} | |
if ($route->scopeStrict()) { | |
$this->validateAllRouteScopes($token, $scopes); | |
} else { | |
$this->validateAnyRouteScopes($token, $scopes); | |
} | |
return $this->resolveResourceOwner($token); | |
} catch (OAuthServerException $exception) { | |
throw new UnauthorizedHttpException( | |
ucfirst($this->getAuthorizationMethod()), | |
$exception->getMessage(), | |
$exception | |
); | |
} | |
} | |
} |
@JulioWar Sorry for the late reply, I didn't get any notification at all
That is my just my custom service for logging in users. You can put whatever you like in the user resolver just like in the original OAuth implementation
@realshadow Do you have an example of your LoginService class? I'd be interested in seeing how you authenticate your users.
@realshadow I'd also love a peak at your LoginService
class. Thanks!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Where is it located
LoginService::class
?