mirror of
https://github.com/elyby/oauth2-server.git
synced 2024-12-26 15:00:19 +05:30
Updated implicit grant to use the new auth request flow
This commit is contained in:
parent
096a4a2883
commit
273ea0ba68
@ -7,23 +7,27 @@ use League\OAuth2\Server\Entities\UserEntityInterface;
|
|||||||
use League\OAuth2\Server\Exception\OAuthServerException;
|
use League\OAuth2\Server\Exception\OAuthServerException;
|
||||||
use League\OAuth2\Server\Repositories\UserRepositoryInterface;
|
use League\OAuth2\Server\Repositories\UserRepositoryInterface;
|
||||||
use League\OAuth2\Server\RequestEvent;
|
use League\OAuth2\Server\RequestEvent;
|
||||||
use League\OAuth2\Server\ResponseTypes\HtmlResponse;
|
use League\OAuth2\Server\RequestTypes\AuthorizationRequest;
|
||||||
use League\OAuth2\Server\ResponseTypes\RedirectResponse;
|
use League\OAuth2\Server\ResponseTypes\RedirectResponse;
|
||||||
use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface;
|
use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface;
|
||||||
use League\OAuth2\Server\TemplateRenderer\RendererInterface;
|
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
|
||||||
class ImplicitGrant extends AbstractAuthorizeGrant
|
class ImplicitGrant extends AbstractAuthorizeGrant
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @param \League\OAuth2\Server\Repositories\UserRepositoryInterface $userRepository
|
* @var \DateInterval
|
||||||
* @param \League\OAuth2\Server\TemplateRenderer\RendererInterface|null $templateRenderer
|
|
||||||
*/
|
*/
|
||||||
public function __construct(UserRepositoryInterface $userRepository, RendererInterface $templateRenderer = null)
|
private $accessTokenTTL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \League\OAuth2\Server\Repositories\UserRepositoryInterface $userRepository
|
||||||
|
* @param \DateInterval $accessTokenTTL
|
||||||
|
*/
|
||||||
|
public function __construct(UserRepositoryInterface $userRepository, \DateInterval $accessTokenTTL)
|
||||||
{
|
{
|
||||||
$this->setUserRepository($userRepository);
|
$this->setUserRepository($userRepository);
|
||||||
$this->refreshTokenTTL = new \DateInterval('P1M');
|
$this->refreshTokenTTL = new \DateInterval('P1M');
|
||||||
$this->templateRenderer = $templateRenderer;
|
$this->accessTokenTTL = $accessTokenTTL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -31,8 +35,7 @@ class ImplicitGrant extends AbstractAuthorizeGrant
|
|||||||
*/
|
*/
|
||||||
public function canRespondToAccessTokenRequest(ServerRequestInterface $request)
|
public function canRespondToAccessTokenRequest(ServerRequestInterface $request)
|
||||||
{
|
{
|
||||||
return (array_key_exists('response_type', $request->getQueryParams())
|
return false;
|
||||||
&& $request->getQueryParams()['response_type'] === 'token');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -46,13 +49,39 @@ class ImplicitGrant extends AbstractAuthorizeGrant
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* Respond to an incoming request.
|
||||||
|
*
|
||||||
|
* @param \Psr\Http\Message\ServerRequestInterface $request
|
||||||
|
* @param \League\OAuth2\Server\ResponseTypes\ResponseTypeInterface $responseType
|
||||||
|
* @param \DateInterval $accessTokenTTL
|
||||||
|
*
|
||||||
|
* @return \League\OAuth2\Server\ResponseTypes\ResponseTypeInterface
|
||||||
*/
|
*/
|
||||||
public function respondToRequest(
|
public function respondToAccessTokenRequest(
|
||||||
ServerRequestInterface $request,
|
ServerRequestInterface $request,
|
||||||
ResponseTypeInterface $responseType,
|
ResponseTypeInterface $responseType,
|
||||||
\DateInterval $accessTokenTTL
|
\DateInterval $accessTokenTTL
|
||||||
) {
|
) {
|
||||||
|
throw new \LogicException('This grant does not used this method');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function canRespondToAuthorizationRequest(ServerRequestInterface $request)
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
array_key_exists('response_type', $request->getQueryParams())
|
||||||
|
&& $request->getQueryParams()['response_type'] === 'token'
|
||||||
|
&& isset($request->getQueryParams()['client_id'])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function validateAuthorizationRequest(ServerRequestInterface $request)
|
||||||
|
{
|
||||||
$clientId = $this->getQueryStringParameter(
|
$clientId = $this->getQueryStringParameter(
|
||||||
'client_id',
|
'client_id',
|
||||||
$request,
|
$request,
|
||||||
@ -72,10 +101,21 @@ class ImplicitGrant extends AbstractAuthorizeGrant
|
|||||||
throw OAuthServerException::invalidClient();
|
throw OAuthServerException::invalidClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
$redirectUriParameter = $this->getQueryStringParameter('redirect_uri', $request, $client->getRedirectUri());
|
$redirectUri = $this->getQueryStringParameter('redirect_uri', $request);
|
||||||
if ($redirectUriParameter !== $client->getRedirectUri()) {
|
if ($redirectUri !== null) {
|
||||||
|
if (
|
||||||
|
is_string($client->getRedirectUri())
|
||||||
|
&& (strcmp($client->getRedirectUri(), $redirectUri) !== 0)
|
||||||
|
) {
|
||||||
$this->getEmitter()->emit(new RequestEvent('client.authentication.failed', $request));
|
$this->getEmitter()->emit(new RequestEvent('client.authentication.failed', $request));
|
||||||
throw OAuthServerException::invalidClient();
|
throw OAuthServerException::invalidClient();
|
||||||
|
} elseif (
|
||||||
|
is_array($client->getRedirectUri())
|
||||||
|
&& in_array($redirectUri, $client->getRedirectUri()) === false
|
||||||
|
) {
|
||||||
|
$this->getEmitter()->emit(new RequestEvent('client.authentication.failed', $request));
|
||||||
|
throw OAuthServerException::invalidClient();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$scopes = $this->validateScopes(
|
$scopes = $this->validateScopes(
|
||||||
@ -83,117 +123,41 @@ class ImplicitGrant extends AbstractAuthorizeGrant
|
|||||||
$client->getRedirectUri()
|
$client->getRedirectUri()
|
||||||
);
|
);
|
||||||
|
|
||||||
$postbackUri = sprintf(
|
|
||||||
'//%s%s',
|
|
||||||
$request->getServerParams()['HTTP_HOST'],
|
|
||||||
$request->getServerParams()['REQUEST_URI']
|
|
||||||
);
|
|
||||||
|
|
||||||
$userId = null;
|
|
||||||
$userHasApprovedClient = null;
|
|
||||||
if ($this->getRequestParameter('action', $request, null) !== null) {
|
|
||||||
$userHasApprovedClient = ($this->getRequestParameter('action', $request) === 'approve');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the user has been authenticated
|
|
||||||
$oauthCookie = $this->getCookieParameter('oauth_authorize_request', $request, null);
|
|
||||||
if ($oauthCookie !== null) {
|
|
||||||
try {
|
|
||||||
$oauthCookiePayload = json_decode($this->decrypt($oauthCookie));
|
|
||||||
if (is_object($oauthCookiePayload)) {
|
|
||||||
$userId = $oauthCookiePayload->user_id;
|
|
||||||
}
|
|
||||||
} catch (\LogicException $e) {
|
|
||||||
throw OAuthServerException::serverError($e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The username + password might be available in $_POST
|
|
||||||
$usernameParameter = $this->getRequestParameter('username', $request, null);
|
|
||||||
$passwordParameter = $this->getRequestParameter('password', $request, null);
|
|
||||||
|
|
||||||
$loginError = null;
|
|
||||||
|
|
||||||
// Assert if the user has logged in already
|
|
||||||
if ($userId === null && $usernameParameter !== null && $passwordParameter !== null) {
|
|
||||||
$userEntity = $this->userRepository->getUserEntityByUserCredentials(
|
|
||||||
$usernameParameter,
|
|
||||||
$passwordParameter,
|
|
||||||
$this->getIdentifier(),
|
|
||||||
$client
|
|
||||||
);
|
|
||||||
|
|
||||||
if ($userEntity instanceof UserEntityInterface) {
|
|
||||||
$userId = $userEntity->getIdentifier();
|
|
||||||
} else {
|
|
||||||
$loginError = 'Incorrect username or password';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The user hasn't logged in yet so show a login form
|
|
||||||
if ($userId === null) {
|
|
||||||
$html = $this->getTemplateRenderer()->renderLogin([
|
|
||||||
'error' => $loginError,
|
|
||||||
'postback_uri' => $this->makeRedirectUri(
|
|
||||||
$postbackUri,
|
|
||||||
$request->getQueryParams()
|
|
||||||
),
|
|
||||||
]);
|
|
||||||
|
|
||||||
$htmlResponse = new HtmlResponse();
|
|
||||||
$htmlResponse->setStatusCode(403);
|
|
||||||
$htmlResponse->setHtml($html);
|
|
||||||
|
|
||||||
return $htmlResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The user hasn't approved the client yet so show an authorize form
|
|
||||||
if ($userId !== null && $userHasApprovedClient === null) {
|
|
||||||
$html = $this->getTemplateRenderer()->renderAuthorize([
|
|
||||||
'client' => $client,
|
|
||||||
'scopes' => $scopes,
|
|
||||||
'postback_uri' => $this->makeRedirectUri(
|
|
||||||
$postbackUri,
|
|
||||||
$request->getQueryParams()
|
|
||||||
),
|
|
||||||
]);
|
|
||||||
|
|
||||||
$htmlResponse = new HtmlResponse();
|
|
||||||
$htmlResponse->setStatusCode(200);
|
|
||||||
$htmlResponse->setHtml($html);
|
|
||||||
$htmlResponse->setHeader('set-cookie', sprintf(
|
|
||||||
'oauth_authorize_request=%s; Expires=%s',
|
|
||||||
urlencode($this->encrypt(
|
|
||||||
json_encode([
|
|
||||||
'user_id' => $userId,
|
|
||||||
])
|
|
||||||
)),
|
|
||||||
(new \DateTime())->add(new \DateInterval('PT5M'))->format('D, d M Y H:i:s e')
|
|
||||||
));
|
|
||||||
|
|
||||||
return $htmlResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The user has either approved or denied the client, so redirect them back
|
|
||||||
$redirectUri = $client->getRedirectUri();
|
|
||||||
$redirectPayload = [];
|
|
||||||
|
|
||||||
$stateParameter = $this->getQueryStringParameter('state', $request);
|
$stateParameter = $this->getQueryStringParameter('state', $request);
|
||||||
if ($stateParameter !== null) {
|
|
||||||
$redirectPayload['state'] = $stateParameter;
|
$authorizationRequest = new AuthorizationRequest();
|
||||||
|
$authorizationRequest->setGrantTypeId($this->getIdentifier());
|
||||||
|
$authorizationRequest->setClient($client);
|
||||||
|
$authorizationRequest->setRedirectUri($redirectUri);
|
||||||
|
$authorizationRequest->setState($stateParameter);
|
||||||
|
$authorizationRequest->setScopes($scopes);
|
||||||
|
|
||||||
|
return $authorizationRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
// THe user approved the client, redirect them back with an access token
|
/**
|
||||||
if ($userHasApprovedClient === true) {
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function completeAuthorizationRequest(AuthorizationRequest $authorizationRequest)
|
||||||
|
{
|
||||||
|
if ($authorizationRequest->getUser() instanceof UserEntityInterface === false) {
|
||||||
|
throw new \LogicException('An instance of UserEntityInterface should be set on the AuthorizationRequest');
|
||||||
|
}
|
||||||
|
|
||||||
// Finalize the requested scopes
|
$finalRedirectUri = ($authorizationRequest->getRedirectUri() === null)
|
||||||
$scopes = $this->scopeRepository->finalizeScopes($scopes, $this->getIdentifier(), $client, $userId);
|
? is_array($authorizationRequest->getClient()->getRedirectUri())
|
||||||
|
? $authorizationRequest->getClient()->getRedirectUri()[0]
|
||||||
|
: $authorizationRequest->getClient()->getRedirectUri()
|
||||||
|
: $authorizationRequest->getRedirectUri();
|
||||||
|
|
||||||
|
// The user approved the client, redirect them back with an access token
|
||||||
|
if ($authorizationRequest->isAuthorizationApproved() === true) {
|
||||||
|
|
||||||
$accessToken = $this->issueAccessToken(
|
$accessToken = $this->issueAccessToken(
|
||||||
$accessTokenTTL,
|
$this->accessTokenTTL,
|
||||||
$client,
|
$authorizationRequest->getClient(),
|
||||||
$userId,
|
$authorizationRequest->getUser()->getIdentifier(),
|
||||||
$scopes
|
$authorizationRequest->getScopes()
|
||||||
);
|
);
|
||||||
|
|
||||||
$redirectPayload['access_token'] = (string) $accessToken->convertToJWT($this->privateKey);
|
$redirectPayload['access_token'] = (string) $accessToken->convertToJWT($this->privateKey);
|
||||||
@ -203,7 +167,7 @@ class ImplicitGrant extends AbstractAuthorizeGrant
|
|||||||
$response = new RedirectResponse();
|
$response = new RedirectResponse();
|
||||||
$response->setRedirectUri(
|
$response->setRedirectUri(
|
||||||
$this->makeRedirectUri(
|
$this->makeRedirectUri(
|
||||||
$redirectUri,
|
$finalRedirectUri,
|
||||||
$redirectPayload,
|
$redirectPayload,
|
||||||
'#'
|
'#'
|
||||||
)
|
)
|
||||||
@ -213,6 +177,9 @@ class ImplicitGrant extends AbstractAuthorizeGrant
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The user denied the client, redirect them back with an error
|
// The user denied the client, redirect them back with an error
|
||||||
throw OAuthServerException::accessDenied('The user denied the request', (string) $redirectUri);
|
throw OAuthServerException::accessDenied(
|
||||||
|
'The user denied the request',
|
||||||
|
$finalRedirectUri
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user