Skip to content

Instantly share code, notes, and snippets.

@realshadow
Last active March 27, 2019 18:12
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save realshadow/f01b7bc781e089a21c64f56c565e29e2 to your computer and use it in GitHub Desktop.
Save realshadow/f01b7bc781e089a21c64f56c565e29e2 to your computer and use it in GitHub Desktop.
<?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,
],
<?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;
});
<?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
Copy link

Where is it located LoginService::class ?

@realshadow
Copy link
Author

@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

@craigwillis85
Copy link

craigwillis85 commented May 3, 2017

@realshadow Do you have an example of your LoginService class? I'd be interested in seeing how you authenticate your users.

@timbroder
Copy link

@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