mirror of
https://github.com/bitinflow/expose.git
synced 2026-03-13 21:45:55 +00:00
99 lines
2.5 KiB
PHP
99 lines
2.5 KiB
PHP
<?php
|
|
|
|
namespace App\Client\Http\Modifiers;
|
|
|
|
use App\Client\Configuration;
|
|
use Illuminate\Support\Arr;
|
|
use Psr\Http\Message\RequestInterface;
|
|
use Ratchet\Client\WebSocket;
|
|
use function GuzzleHttp\Psr7\str;
|
|
|
|
class CheckBasicAuthentication
|
|
{
|
|
/** @var Configuration */
|
|
protected $configuration;
|
|
|
|
public function __construct(Configuration $configuration)
|
|
{
|
|
$this->configuration = $configuration;
|
|
}
|
|
|
|
public function handle(RequestInterface $request, ?WebSocket $proxyConnection): ?RequestInterface
|
|
{
|
|
if (! $this->requiresAuthentication() || is_null($proxyConnection)) {
|
|
return $request;
|
|
}
|
|
|
|
$username = $this->getAuthorizationUsername($request);
|
|
|
|
if (is_null($username)) {
|
|
$proxyConnection->send(
|
|
str(new \GuzzleHttp\Psr7\Response(401, [
|
|
'WWW-Authenticate' => 'Basic realm=Expose'
|
|
], 'Unauthorized'))
|
|
);
|
|
$proxyConnection->close();
|
|
return null;
|
|
}
|
|
|
|
return $request;
|
|
}
|
|
|
|
protected function getAuthorizationUsername(RequestInterface $request): ?string
|
|
{
|
|
$authorization = $this->parseAuthorizationHeader(Arr::get($request->getHeaders(), 'authorization.0', ''));
|
|
$credentials = $this->getCredentials();
|
|
|
|
if (empty($authorization)) {
|
|
return null;
|
|
}
|
|
|
|
if (!array_key_exists($authorization['username'], $credentials)) {
|
|
return null;
|
|
}
|
|
|
|
if ($credentials[$authorization['username']] !== $authorization['password']) {
|
|
return null;
|
|
}
|
|
|
|
return $authorization['username'];
|
|
}
|
|
|
|
protected function parseAuthorizationHeader(string $header)
|
|
{
|
|
if (strpos($header, 'Basic') !== 0) {
|
|
return null;
|
|
}
|
|
|
|
$header = base64_decode(substr($header, 6));
|
|
|
|
if ($header === false) {
|
|
return null;
|
|
}
|
|
|
|
$header = explode(':', $header, 2);
|
|
|
|
return [
|
|
'username' => $header[0],
|
|
'password' => isset($header[1]) ? $header[1] : null,
|
|
];
|
|
}
|
|
|
|
protected function requiresAuthentication(): bool
|
|
{
|
|
return !empty($this->getCredentials());
|
|
}
|
|
|
|
protected function getCredentials()
|
|
{
|
|
try {
|
|
$credentials = explode(':', $this->configuration->auth());
|
|
return [
|
|
$credentials[0] => $credentials[1],
|
|
];
|
|
} catch (\Exception $e) {
|
|
return [];
|
|
}
|
|
}
|
|
}
|