AuthCode grant

This commit is contained in:
Alex Bilbie
2014-04-06 19:14:46 +01:00
parent 82f7c7abaf
commit 2aa318cfd7
4 changed files with 786 additions and 83 deletions

View File

@@ -22,6 +22,48 @@ use Symfony\Component\HttpFoundation\ParameterBag;
*/
class AuthCode extends AbstractToken
{
/**
* Redirect URI
* @var string
*/
protected $redirectUri = '';
/**
* Set the redirect URI for the authorization request
* @param string $redirectUri
* @return self
*/
public function setRedirectUri($redirectUri)
{
$this->redirectUri = $redirectUri;
return $this;
}
/**
* Get the redirect URI
* @return string
*/
public function getRedirectUri()
{
return $this->redirectUri;
}
/**
* [generateRedirectUri description]
* @param string $state The state parameter if set by the client
* @param string $queryDelimeter The query delimiter ('?' for auth code grant, '#' for implicit grant)
* @return string
*/
public function generateRedirectUri($state = null, $queryDelimeter = '?')
{
$uri = $this->getRedirectUri();
$uri .= (strstr($this->getRedirectUri(), $queryDelimeter) === false) ? $queryDelimeter : '&';
return $uri.http_build_query([
'code' => $this->getToken(),
'state' => $state
]);
}
/**
* {@inheritdoc}
*/

View File

@@ -11,21 +11,26 @@
namespace League\OAuth2\Server\Grant;
use League\OAuth2\Server\AuthorizationServer;
use League\OAuth2\Server\Request;
use League\OAuth2\Server\Authorization;
use League\OAuth2\Server\Exception;
use League\OAuth2\Server\Entity\Client;
use League\OAuth2\Server\Entity\RefreshToken;
use League\OAuth2\Server\Entity\Session;
use League\OAuth2\Server\Entity\AccessToken;
use League\OAuth2\Server\Entity\Scope;
use League\OAuth2\Server\Entity\AuthCode as AC;
use League\OAuth2\Server\Util\SecureKey;
use League\OAuth2\Server\Storage\SessionInterface;
use League\OAuth2\Server\Storage\ClientInterface;
use League\OAuth2\Server\Storage\ScopeInterface;
use League\OAuth2\Server\Exception\ClientException;
/**
* Auth code grant class
*/
class AuthCode implements GrantTypeInterface {
use GrantTrait;
class AuthCode extends AbstractGrant
{
/**
* Grant identifier
* @var string
@@ -74,9 +79,7 @@ class AuthCode implements GrantTypeInterface {
*/
public function checkAuthoriseParams()
{
// Auth params
$authParams = $this->server->getParam(array('client_id', 'redirect_uri', 'response_type', 'scope', 'state'), 'get', $inputParams);
// Get required params
$clientId = $this->server->getRequest()->request->get('client_id', null);
if (is_null($clientId)) {
throw new ClientException(
@@ -150,28 +153,27 @@ class AuthCode implements GrantTypeInterface {
* @param array $authParams The authorise request $_GET parameters
* @return string An authorisation code
*/
public function newAuthoriseRequest($type =, $typeId, $authParams = [])
public function newAuthoriseRequest($type, $typeId, $authParams = [])
{
// Generate an auth code
$authCode = SecureKey::make();
// Create a new session
$session = new Session($this->server);
$session->setOwner($type, $typeId);
$session->associateClient($authParams['client']);
$session->save();
// Associate a redirect URI
$this->server->getStorage('session')->associateRedirectUri($sessionId, $authParams['redirect_uri']);
// Create a new auth code
$authCode = new AC($this->server);
$authCode->setToken(SecureKey::make());
$authCode->setRedirectUri($authParams['redirect_uri']);
// Associate the auth code
$authCodeId = $this->server->getStorage('session')->associateAuthCode($sessionId, $authCode, time() + $this->authTokenTTL);
// Associate the scopes to the auth code
foreach ($authParams['scopes'] as $scope) {
$this->server->getStorage('session')->associateAuthCodeScope($authCodeId, $scope['id']);
$authCode->associateScope($scope);
}
return $authCode;
$authCode->setSession($session);
$authCode->save();
return $authCode->generateRedirectUri($authParams['state']);
}
/**
@@ -182,78 +184,107 @@ class AuthCode implements GrantTypeInterface {
public function completeFlow($inputParams = null)
{
// Get the required params
$authParams = $this->server->getParam(array('client_id', 'client_secret', 'redirect_uri', 'code'), 'post', $inputParams);
if (is_null($authParams['client_id'])) {
throw new Exception\ClientException(sprintf($this->server->getExceptionMessage('invalid_request'), 'client_id'), 0);
$clientId = $this->server->getRequest()->request->get('client_id', null);
if (is_null($clientId)) {
throw new ClientException(
sprintf(AuthorizationServer::getExceptionMessage('invalid_request'), 'client_id'),
0
);
}
if (is_null($authParams['client_secret'])) {
throw new Exception\ClientException(sprintf($this->server->getExceptionMessage('invalid_request'), 'client_secret'), 0);
$clientSecret = $this->server->getRequest()->request->get('client_secret', null);
if (is_null($clientSecret)) {
throw new ClientException(
sprintf(AuthorizationServer::getExceptionMessage('invalid_request'), 'client_secret'),
0
);
}
if (is_null($authParams['redirect_uri'])) {
throw new Exception\ClientException(sprintf($this->server->getExceptionMessage('invalid_request'), 'redirect_uri'), 0);
$redirectUri = $this->server->getRequest()->request->get('redirect_uri', null);
if (is_null($redirectUri)) {
throw new ClientException(
sprintf(AuthorizationServer::getExceptionMessage('invalid_request'), 'redirect_uri'),
0
);
}
// Validate client ID and redirect URI
$clientDetails = $this->server->getStorage('client')->getClient($authParams['client_id'], $authParams['client_secret'], $authParams['redirect_uri'], $this->identifier);
if ($clientDetails === false) {
throw new Exception\ClientException($this->server->getExceptionMessage('invalid_client'), 8);
}
$authParams['client_details'] = $clientDetails;
// Validate the authorization code
if (is_null($authParams['code'])) {
throw new Exception\ClientException(sprintf($this->server->getExceptionMessage('invalid_request'), 'code'), 0);
}
// Verify the authorization code matches the client_id and the request_uri
$authCodeDetails = $this->server->getStorage('session')->validateAuthCode($authParams['client_id'], $authParams['redirect_uri'], $authParams['code']);
if ( ! $authCodeDetails) {
throw new Exception\ClientException(sprintf($this->server->getExceptionMessage('invalid_grant'), 'code'), 9);
}
// Get any associated scopes
$scopes = $this->server->getStorage('session')->getAuthCodeScopes($authCodeDetails['authcode_id']);
// A session ID was returned so update it with an access token and remove the authorisation code
$accessToken = SecureKey::make();
$accessTokenExpiresIn = ($this->accessTokenTTL !== null) ? $this->accessTokenTTL : $this->server->getAccessTokenTTL();
$accessTokenExpires = time() + $accessTokenExpiresIn;
// Remove the auth code
$this->server->getStorage('session')->removeAuthCode($authCodeDetails['session_id']);
// Create an access token
$accessTokenId = $this->server->getStorage('session')->associateAccessToken($authCodeDetails['session_id'], $accessToken, $accessTokenExpires);
// Associate scopes with the access token
if (count($scopes) > 0) {
foreach ($scopes as $scope) {
$this->server->getStorage('session')->associateScope($accessTokenId, $scope['scope_id']);
}
}
$response = array(
'access_token' => $accessToken,
'token_type' => 'Bearer',
'expires' => $accessTokenExpires,
'expires_in' => $accessTokenExpiresIn
// Validate client ID and client secret
$client = $this->server->getStorage('client')->get(
$clientId,
$clientSecret,
$redirectUri,
$this->getIdentifier()
);
if (($client instanceof Client) === false) {
throw new ClientException(AuthorizationServer::getExceptionMessage('invalid_client'), 8);
}
// Validate the auth code
$authCode = $this->server->getRequest()->request->get('code', null);
if (is_null($authCode)) {
throw new ClientException(
sprintf(AuthorizationServer::getExceptionMessage('invalid_request'), 'code'),
0
);
}
$code = $this->server->getStorage('auth_code')->get($authCode);
if (($code instanceof AC) === false) {
throw new ClientException(
sprintf(AuthorizationServer::getExceptionMessage('invalid_request'), 'code'),
9
);
}
// Check redirect URI presented matches redirect URI originally used in authorise request
if ($code->getRedirectUri() !== $redirectUri) {
throw new ClientException(
sprintf(AuthorizationServer::getExceptionMessage('invalid_request'), 'redirect_uri'),
9
);
}
$session = $code->getSession();
$authCodeScopes = $code->getScopes();
// Generate the access token
$accessToken = new AccessToken($this->server);
$accessToken->setToken(SecureKey::make());
$accessToken->setExpireTime($this->server->getAccessTokenTTL() + time());
foreach ($authCodeScopes as $authCodeScope) {
$session->associateScope($authCodeScope);
}
$response = [
'access_token' => $accessToken->getToken(),
'token_type' => 'Bearer',
'expires' => $accessToken->getExpireTime(),
'expires_in' => $this->server->getAccessTokenTTL()
];
// Associate a refresh token if set
if ($this->server->hasGrantType('refresh_token')) {
$refreshToken = SecureKey::make();
$refreshTokenTTL = time() + $this->server->getGrantType('refresh_token')->getRefreshTokenTTL();
$this->server->getStorage('session')->associateRefreshToken($accessTokenId, $refreshToken, $refreshTokenTTL, $authParams['client_id']);
$response['refresh_token'] = $refreshToken;
$refreshToken = new RefreshToken($this->server);
$refreshToken->setToken(SecureKey::make());
$refreshToken->setExpireTime($this->server->getGrantType('refresh_token')->getRefreshTokenTTL() + time());
$response['refresh_token'] = $refreshToken->getToken();
}
// Expire the auth code
$code->expire();
// Save all the things
$session->save();
$accessToken->setSession($session);
$accessToken->save();
if ($this->server->hasGrantType('refresh_token')) {
$refreshToken->setAccessToken($accessToken);
$refreshToken->save();
}
return $response;
}
}