mirror of
https://github.com/elyby/oauth2-server.git
synced 2024-12-22 21:19:46 +05:30
Added MAC TokenType
This commit is contained in:
parent
f9e56ff62a
commit
ae5dd9ce65
141
src/TokenType/MAC.php
Normal file
141
src/TokenType/MAC.php
Normal file
@ -0,0 +1,141 @@
|
||||
<?php
|
||||
/**
|
||||
* OAuth 2.0 MAC Token Type
|
||||
*
|
||||
* @package league/oauth2-server
|
||||
* @author Alex Bilbie <hello@alexbilbie.com>
|
||||
* @copyright Copyright (c) Alex Bilbie
|
||||
* @license http://mit-license.org/
|
||||
* @link https://github.com/thephpleague/oauth2-server
|
||||
*/
|
||||
|
||||
namespace League\OAuth2\Server\TokenType;
|
||||
|
||||
use League\OAuth2\Server\Util\SecureKey;
|
||||
use Symfony\Component\HttpFoundation\ParameterBag;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* MAC Token Type
|
||||
*/
|
||||
class MAC extends AbstractTokenType implements TokenTypeInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function generateResponse()
|
||||
{
|
||||
$macKey = SecureKey::generate();
|
||||
$this->server->getMacStorage()->create($macKey, $this->getParam('access_token'));
|
||||
|
||||
$response = [
|
||||
'access_token' => $this->getParam('access_token'),
|
||||
'token_type' => 'mac',
|
||||
'expires_in' => $this->getParam('expires_in'),
|
||||
'mac_key' => $macKey,
|
||||
'mac_algorithm' => 'hmac-sha-256',
|
||||
];
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function determineAccessTokenInHeader(Request $request)
|
||||
{
|
||||
if ($request->headers->has('Authorization') === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
$header = $request->headers->get('Authorization');
|
||||
|
||||
if (substr($header, 0, 4) !== 'MAC ') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find all the parameters expressed in the header
|
||||
$paramsRaw = explode(',', substr($header, 4));
|
||||
$params = new ParameterBag();
|
||||
|
||||
array_map(function ($param) use (&$params) {
|
||||
$param = trim($param);
|
||||
|
||||
preg_match_all('/([a-zA-Z]*)="([\w=]*)"/', $param, $matches);
|
||||
|
||||
if (count($matches) !== 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
$key = reset($matches[1]);
|
||||
$value = trim(reset($matches[2]));
|
||||
|
||||
if (empty($value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$params->add($key, $value);
|
||||
}, $paramsRaw);
|
||||
|
||||
// Validate parameters
|
||||
if ($params->has('id') === false || $params->has('ts') === false || $params->has('nonce') === false || $params->has('mac') === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((int) $params->get('ts') !== time()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$accessToken = $params->get('id');
|
||||
$timestamp = (int) $params->get('ts');
|
||||
$nonce = $params->get('nonce');
|
||||
$signature = $params->get('mac');
|
||||
|
||||
// Try to find the MAC key for the access token
|
||||
$macKey = $this->server->getMacStorage()->getByAccessToken($accessToken);
|
||||
|
||||
if ($macKey === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate and compare the signature
|
||||
$calculatedSignatureParts = [
|
||||
$timestamp,
|
||||
$nonce,
|
||||
strtoupper($request->getMethod()),
|
||||
$request->getUri(),
|
||||
$request->getHost(),
|
||||
$request->getPort(),
|
||||
];
|
||||
|
||||
if ($params->has('ext')) {
|
||||
$calculatedSignatureParts[] = $params->get('ext');
|
||||
}
|
||||
|
||||
$calculatedSignature = base64_encode(hash_hmac('sha256', implode("\n", $calculatedSignatureParts), $macKey)));
|
||||
|
||||
// Return the access token if the signature matches
|
||||
return ($this->hash_equals($calculatedSignature, $signature)) ? $accessToken : null;
|
||||
}
|
||||
|
||||
private function hash_equals($knownString, $userString)
|
||||
{
|
||||
if (!function_exists('hash_equals')) {
|
||||
function hash_equals($knownString, $userString)
|
||||
{
|
||||
if (strlen($knownString) !== strlen($userString)) {
|
||||
return false;
|
||||
}
|
||||
$len = strlen($knownString);
|
||||
$result = 0;
|
||||
for ($i = 0; $i < $len; $i++) {
|
||||
$result |= (ord($knownString[$i]) ^ ord($userString[$i]));
|
||||
}
|
||||
// They are only identical strings if $result is exactly 0...
|
||||
return 0 === $result;
|
||||
}
|
||||
}
|
||||
|
||||
return hash_equals($knownString, $userString);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user