mirror of
https://github.com/elyby/oauth2-server.git
synced 2024-12-16 18:19:47 +05:30
Added the user_credentials and refresh_token grants. Fixed expires_in so it is inline with the spec, but added expires for the old usage of expires_in. Made redirect_uri in oauth_sessions ALLOW NULL since user_credential grants don't have a redirect
This commit is contained in:
parent
41d8a1efa3
commit
0f6f5e2939
@ -21,11 +21,12 @@ CREATE TABLE `client_endpoints` (
|
|||||||
CREATE TABLE `oauth_sessions` (
|
CREATE TABLE `oauth_sessions` (
|
||||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||||
`client_id` varchar(40) NOT NULL DEFAULT '',
|
`client_id` varchar(40) NOT NULL DEFAULT '',
|
||||||
`redirect_uri` varchar(250) NOT NULL DEFAULT '',
|
`redirect_uri` varchar(250) DEFAULT '',
|
||||||
`owner_type` enum('user','client') NOT NULL DEFAULT 'user',
|
`owner_type` enum('user','client') NOT NULL DEFAULT 'user',
|
||||||
`owner_id` varchar(255) DEFAULT NULL,
|
`owner_id` varchar(255) DEFAULT NULL,
|
||||||
`auth_code` varchar(40) DEFAULT '',
|
`auth_code` varchar(40) DEFAULT '',
|
||||||
`access_token` varchar(40) DEFAULT '',
|
`access_token` varchar(40) DEFAULT '',
|
||||||
|
`refresh_token` varchar(40) NOT NULL,
|
||||||
`access_token_expires` int(10) DEFAULT NULL,
|
`access_token_expires` int(10) DEFAULT NULL,
|
||||||
`stage` enum('requested','granted') NOT NULL DEFAULT 'requested',
|
`stage` enum('requested','granted') NOT NULL DEFAULT 'requested',
|
||||||
`first_requested` int(10) unsigned NOT NULL,
|
`first_requested` int(10) unsigned NOT NULL,
|
||||||
|
@ -77,6 +77,7 @@ interface Database
|
|||||||
$typeId = null,
|
$typeId = null,
|
||||||
$authCode = null,
|
$authCode = null,
|
||||||
$accessToken = null,
|
$accessToken = null,
|
||||||
|
$refreshToken = null,
|
||||||
$accessTokenExpire = null,
|
$accessTokenExpire = null,
|
||||||
$stage = 'requested'
|
$stage = 'requested'
|
||||||
);
|
);
|
||||||
@ -102,6 +103,7 @@ interface Database
|
|||||||
$sessionId,
|
$sessionId,
|
||||||
$authCode = null,
|
$authCode = null,
|
||||||
$accessToken = null,
|
$accessToken = null,
|
||||||
|
$refreshToken = null,
|
||||||
$accessTokenExpire = null,
|
$accessTokenExpire = null,
|
||||||
$stage = 'requested'
|
$stage = 'requested'
|
||||||
);
|
);
|
||||||
@ -125,6 +127,26 @@ interface Database
|
|||||||
$typeId
|
$typeId
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the refresh token
|
||||||
|
*
|
||||||
|
* Database query:
|
||||||
|
*
|
||||||
|
* <code>
|
||||||
|
* UPDATE oauth_sessions SET access_token = $newAccessToken, refresh_token =
|
||||||
|
* $newRefreshToken, access_toke_expires = $accessTokenExpires, last_updated = UNIX_TIMESTAMP(NOW()) WHERE
|
||||||
|
* refresh_token = $currentRefreshToken
|
||||||
|
* </code>
|
||||||
|
*
|
||||||
|
* @param string $currentRefreshToken The session's current refresh token
|
||||||
|
* @param string $newAccessToken The new access token for this session
|
||||||
|
* @param string $newRefreshToken The new refresh token for the session
|
||||||
|
* @param int $accessTokenExpires The UNIX timestamp of when the new token expires
|
||||||
|
* @return bool Whether the $currentRefreshToken was valid or not.
|
||||||
|
*/
|
||||||
|
public function refreshToken($currentRefreshToken, $newAccessToken, $newRefreshToken, $accessTokenExpires);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate that an authorisation code is valid
|
* Validate that an authorisation code is valid
|
||||||
*
|
*
|
||||||
|
@ -31,7 +31,7 @@ class Server
|
|||||||
*/
|
*/
|
||||||
private $_config = array(
|
private $_config = array(
|
||||||
'scope_delimeter' => ',',
|
'scope_delimeter' => ',',
|
||||||
'access_token_ttl' => null
|
'access_token_ttl' => 3600
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -47,7 +47,9 @@ class Server
|
|||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private $_grantTypes = array(
|
private $_grantTypes = array(
|
||||||
'authorization_code'
|
'authorization_code',
|
||||||
|
'user_credentials',
|
||||||
|
'refresh_token',
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -84,7 +86,9 @@ class Server
|
|||||||
'temporarily_unavailable' => 'The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server.',
|
'temporarily_unavailable' => 'The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server.',
|
||||||
'unsupported_grant_type' => 'The authorization grant type is not supported by the authorization server',
|
'unsupported_grant_type' => 'The authorization grant type is not supported by the authorization server',
|
||||||
'invalid_client' => 'Client authentication failed',
|
'invalid_client' => 'Client authentication failed',
|
||||||
'invalid_grant' => 'The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client. Check the "%s" parameter.'
|
'invalid_grant' => 'The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client. Check the "%s" parameter.',
|
||||||
|
'invalid_credentials' => 'Invalid Credentials',
|
||||||
|
'invalid_refresh' => 'Invalid Refresh Token',
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -284,7 +288,7 @@ class Server
|
|||||||
* @param string $accessToken The access token (default = null)
|
* @param string $accessToken The access token (default = null)
|
||||||
* @return string An authorisation code
|
* @return string An authorisation code
|
||||||
*/
|
*/
|
||||||
private function newAuthCode($clientId, $type, $typeId, $redirectUri, $scopes = array(), $accessToken = null)
|
private function newAuthCode($clientId, $type, $typeId, $redirectUri, $scopes = array(), $accessToken = null, $refreshToken = null)
|
||||||
{
|
{
|
||||||
$authCode = $this->generateCode();
|
$authCode = $this->generateCode();
|
||||||
|
|
||||||
@ -299,6 +303,7 @@ class Server
|
|||||||
$typeId,
|
$typeId,
|
||||||
$authCode,
|
$authCode,
|
||||||
$accessToken,
|
$accessToken,
|
||||||
|
$refreshToken,
|
||||||
'requested'
|
'requested'
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -374,9 +379,17 @@ class Server
|
|||||||
return $this->completeAuthCodeGrant($authParams, $params);
|
return $this->completeAuthCodeGrant($authParams, $params);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'user_credentials':
|
||||||
|
return $this->completeUserCredentialsGrant($authParams, $params);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'refresh_token': // Refresh token
|
case 'refresh_token': // Refresh token
|
||||||
|
return $this->completeRefreshTokenGrant($authParams, $params);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'password': // Resource owner password credentials grant
|
case 'password': // Resource owner password credentials grant
|
||||||
case 'client_credentials': // Client credentials grant
|
case 'client_credentials': // Client credentials grant
|
||||||
|
|
||||||
default: // Unsupported
|
default: // Unsupported
|
||||||
throw new ServerException($this->errors['server_error'] . 'Tried to process an unsuppported grant type.', 5);
|
throw new ServerException($this->errors['server_error'] . 'Tried to process an unsuppported grant type.', 5);
|
||||||
break;
|
break;
|
||||||
@ -479,16 +492,19 @@ class Server
|
|||||||
// remove the authorisation code, change the stage to 'granted'
|
// remove the authorisation code, change the stage to 'granted'
|
||||||
|
|
||||||
$accessToken = $this->generateCode();
|
$accessToken = $this->generateCode();
|
||||||
|
$refreshToken = $this->generateCode();
|
||||||
|
|
||||||
$accessTokenExpires = ($this->_config['access_token_ttl'] === null) ?
|
$accessTokenExpires = ($this->_config['access_token_ttl'] === null) ?
|
||||||
null :
|
null :
|
||||||
time() + $this->_config['access_token_ttl'];
|
time() + $this->_config['access_token_ttl'];
|
||||||
|
$accessTokenExpiresIn = ($this->_config['access_token_ttl'] === null) ? 0 : $this->_config['access_token_ttl'];
|
||||||
|
|
||||||
$this->_dbCall(
|
$this->_dbCall(
|
||||||
'updateSession',
|
'updateSession',
|
||||||
$session['id'],
|
$session['id'],
|
||||||
null,
|
null,
|
||||||
$accessToken,
|
$accessToken,
|
||||||
|
$refreshToken,
|
||||||
$accessTokenExpires,
|
$accessTokenExpires,
|
||||||
'granted'
|
'granted'
|
||||||
);
|
);
|
||||||
@ -497,17 +513,177 @@ class Server
|
|||||||
$this->_dbCall(
|
$this->_dbCall(
|
||||||
'updateSessionScopeAccessToken',
|
'updateSessionScopeAccessToken',
|
||||||
$session['id'],
|
$session['id'],
|
||||||
$accessToken
|
$accessToken,
|
||||||
|
$refreshToken
|
||||||
);
|
);
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'access_token' => $accessToken,
|
'access_token' => $accessToken,
|
||||||
|
'refresh_token' => $refreshToken,
|
||||||
'token_type' => 'bearer',
|
'token_type' => 'bearer',
|
||||||
'expires_in' => $this->_config['access_token_ttl']
|
'expires' => $accessTokenExpires,
|
||||||
|
'expires_in' => $accessTokenExpiresIn
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Complete the user credentials grant
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
*
|
||||||
|
* @param array $authParams Array of parsed $_POST keys
|
||||||
|
* @param array $params Generated parameters from issueAccessToken()
|
||||||
|
*
|
||||||
|
* @return array Authorise request parameters
|
||||||
|
*/
|
||||||
|
private function completeUserCredentialsGrant($authParams = array(), $params = array())
|
||||||
|
{
|
||||||
|
$params = array();
|
||||||
|
|
||||||
|
if ( ! isset($authParams['user_auth_callback'])) {
|
||||||
|
throw new \InvalidArgumentException('You must set a user_auth_callback when using the user_credentials grant type.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Client ID
|
||||||
|
if ( ! isset($authParams['client_id']) && ! isset($_POST['client_id'])) {
|
||||||
|
throw new ClientException(sprintf($this->errors['invalid_request'], 'client_id'), 0);
|
||||||
|
} else {
|
||||||
|
$params['client_id'] = (isset($authParams['client_id'])) ?
|
||||||
|
$authParams['client_id'] :
|
||||||
|
$_POST['client_id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Client secret
|
||||||
|
if ( ! isset($authParams['client_secret']) && ! isset($_POST['client_secret'])) {
|
||||||
|
throw new ClientException(sprintf($this->errors['invalid_request'], 'client_secret'), 0);
|
||||||
|
} else {
|
||||||
|
$params['client_secret'] = (isset($authParams['client_secret'])) ?
|
||||||
|
$authParams['client_secret'] :
|
||||||
|
$_POST['client_secret'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate client ID and redirect URI
|
||||||
|
$clientDetails = $this->_dbCall(
|
||||||
|
'validateClient',
|
||||||
|
$params['client_id'],
|
||||||
|
$params['client_secret'],
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($clientDetails === false) {
|
||||||
|
throw new \Oauth2\Authentication\ClientException($this->errors['invalid_client'], 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for grant
|
||||||
|
if ( ! isset($_POST['grant_type'])) {
|
||||||
|
throw new \Oauth2\Authentication\ClientException(sprintf($this->errors['invalid_request'], 'client_id'), 0);
|
||||||
|
} else {
|
||||||
|
$params['grant_type'] = $_POST['grant_type'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($params['grant_type'] == 'user_credentials')
|
||||||
|
{
|
||||||
|
// Check if user's u+p are correct
|
||||||
|
$userId = call_user_func($authParams['user_auth_callback']);
|
||||||
|
|
||||||
|
if ($userId === false)
|
||||||
|
{
|
||||||
|
throw new \Oauth2\Authentication\ClientException($this->errors['invalid_credentials'], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Generate an access token
|
||||||
|
$accessToken = $this->generateCode();
|
||||||
|
$refreshToken = $this->generateCode();
|
||||||
|
|
||||||
|
$accessTokenExpires = ($this->_config['access_token_ttl'] === null) ?
|
||||||
|
null :
|
||||||
|
time() + $this->_config['access_token_ttl'];
|
||||||
|
$accessTokenExpiresIn = ($this->_config['access_token_ttl'] === null) ? 0 : $this->_config['access_token_ttl'];
|
||||||
|
|
||||||
|
// Delete any existing sessions just to be sure
|
||||||
|
$this->_dbCall('deleteSession', $params['client_id'], 'user', $userId);
|
||||||
|
|
||||||
|
// Create a new session
|
||||||
|
$this->_dbCall('newSession', $params['client_id'], null, 'user', $userId, null, $accessToken, $refreshToken, $accessTokenExpires, 'granted');
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'access_token' => $accessToken,
|
||||||
|
'refresh_token' => $refreshToken,
|
||||||
|
'token_type' => 'bearer',
|
||||||
|
'expires' => $accessTokenExpires,
|
||||||
|
'expires_in' => $accessTokenExpiresIn
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new \Oauth2\Authentication\ClientException($this->errors['unsupported_grant_type'], 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Complete the refresh token grant
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
*
|
||||||
|
* @param array $authParams Array of parsed $_POST keys
|
||||||
|
* @param array $params Generated parameters from issueAccessToken()
|
||||||
|
*
|
||||||
|
* @return array Authorise request parameters
|
||||||
|
*/
|
||||||
|
private function completeRefreshTokenGrant($authParams = array(), $params = array())
|
||||||
|
{
|
||||||
|
$params = array();
|
||||||
|
|
||||||
|
// Check for grant
|
||||||
|
if ( ! isset($_POST['grant_type'])) {
|
||||||
|
throw new \Oauth2\Authentication\ClientException(sprintf($this->errors['invalid_request'], 'grant_type'), 0);
|
||||||
|
} else {
|
||||||
|
$params['grant_type'] = $_POST['grant_type'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! isset($authParams['refresh_token']) && ! isset($_POST['refresh_token'])) {
|
||||||
|
throw new ClientException(sprintf($this->errors['invalid_request'], 'refresh_token'), 0);
|
||||||
|
} else {
|
||||||
|
$params['refresh_token'] = (isset($authParams['refresh_token'])) ?
|
||||||
|
$authParams['refresh_token'] :
|
||||||
|
$_POST['refresh_token'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($params['grant_type'] == 'refresh_token')
|
||||||
|
{
|
||||||
|
// Generate an access token
|
||||||
|
$accessToken = $this->generateCode();
|
||||||
|
$refreshToken = $this->generateCode();
|
||||||
|
|
||||||
|
$accessTokenExpires = ($this->_config['access_token_ttl'] === null) ?
|
||||||
|
null :
|
||||||
|
time() + $this->_config['access_token_ttl'];
|
||||||
|
|
||||||
|
$accessTokenExpiresIn = ($this->_config['access_token_ttl'] === null) ? 0 : $this->_config['access_token_ttl'];
|
||||||
|
|
||||||
|
// Delete any existing sessions just to be sure
|
||||||
|
$result = $this->_dbCall('refreshToken', $params['refresh_token'], $accessToken, $refreshToken, $accessTokenExpires);
|
||||||
|
|
||||||
|
if ( ! $result) {
|
||||||
|
throw new \Oauth2\Authentication\ClientException($this->errors['invalid_refresh'], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'access_token' => $accessToken,
|
||||||
|
'refresh_token' => $refreshToken,
|
||||||
|
'token_type' => 'bearer',
|
||||||
|
'expires' => $accessTokenExpires,
|
||||||
|
'expires_in' => $accessTokenExpiresIn
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
throw new \Oauth2\Authentication\ClientException($this->errors['unsupported_grant_type'], 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates the redirect uri with appended params
|
* Generates the redirect uri with appended params
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user