- WIP on authentication
This commit is contained in:
1 parent
9ae3e2d6f9
commit
0f2886b266
6 files changed
+189
-30
No files matched your search
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace Ulmus\User\Authorize\Header;
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Ulmus\User\Entity\DigestAuthUserInterface;
|
||||
|
||||
class DigestMethod
|
||||
{
|
||||
public function __construct(
|
||||
protected DigestAuthUserInterface $user,
|
||||
protected string|array $arguments
|
||||
) {}
|
||||
|
||||
public function execute(ServerRequestInterface $request) : bool
|
||||
{
|
||||
$arguments = $this->parseDigestArguments($this->arguments);
|
||||
|
||||
if (empty($arguments['username'])) {
|
||||
throw new \InvalidArgumentException("A 'username' key is required to authenticate using Digest");
|
||||
}
|
||||
|
||||
$isSess = stripos($arguments['algorithm'] ?? "", "-SESS") !== false;
|
||||
|
||||
$hashMethod = $this->getDigestAlgorithmHash($arguments);
|
||||
|
||||
$arguments['nc'] = str_pad($arguments['nc'] ?? "1", 8, '0', STR_PAD_LEFT);
|
||||
|
||||
$ha1 = $this->getSecretHash();
|
||||
|
||||
if ($isSess) {
|
||||
$ha1 = hash($hashMethod, implode(':', [
|
||||
$ha1, $arguments['nonce'] , $arguments['cnonce']
|
||||
]));
|
||||
}
|
||||
|
||||
switch($arguments['qop'] ?? 'auth') {
|
||||
case 'auth-int':
|
||||
$ha2 = hash($hashMethod, implode(':', [
|
||||
strtoupper($request->getMethod()), $arguments['uri'], hash($hashMethod, $body ?? "")
|
||||
]));
|
||||
break;
|
||||
|
||||
case 'auth':
|
||||
default:
|
||||
$ha2 = hash($hashMethod, implode(':', [
|
||||
strtoupper($request->getMethod()), $arguments['uri']
|
||||
]));
|
||||
break;
|
||||
}
|
||||
|
||||
if (isset($arguments['qop'])) {
|
||||
$response = hash($hashMethod, implode(':', [
|
||||
$ha1, $arguments['nonce'], $arguments['nc'], $arguments['cnonce'], $arguments['qop'], $ha2
|
||||
]));
|
||||
}
|
||||
else {
|
||||
$response = hash($hashMethod, implode(':', [
|
||||
$ha1, $arguments['nonce'], $ha2
|
||||
]));
|
||||
}
|
||||
|
||||
return $response === $arguments['response'];
|
||||
}
|
||||
|
||||
|
||||
protected function parseDigestArguments(string|array $arguments) : array
|
||||
{
|
||||
if (is_string($arguments)) {
|
||||
$keys = [ 'nonce', 'nc', 'cnonce', 'qop', 'username', 'uri', 'realm', 'response', 'opaque', 'algorithm' ];
|
||||
|
||||
# From https://www.php.net/manual/en/features.http-auth.php
|
||||
preg_match_all('@(' . implode('|', $keys) . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', $arguments, $matches, PREG_SET_ORDER);
|
||||
|
||||
$arguments = [];
|
||||
|
||||
foreach ($matches as $match) {
|
||||
$arguments[$match[1]] = $match[3] ?: $match[4];
|
||||
}
|
||||
}
|
||||
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
protected function getDigestAlgorithmHash(array $arguments) : string
|
||||
{
|
||||
switch(strtoupper($arguments['algorithm'] ?? "")) {
|
||||
case "SHA-512-256":
|
||||
case "SHA-512-256-SESS":
|
||||
return "sha512/256";
|
||||
|
||||
case "SHA-256":
|
||||
case "SHA-256-SESS":
|
||||
return "sha256";
|
||||
|
||||
default:
|
||||
case 'MD5-SESS':
|
||||
case 'MD5':
|
||||
return "md5";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user