Files
hdk-admin/src/Middleware/PermissionMiddleware.php
李东云 2625bd2826 chore: 修改文件权限并添加脚本和CI配置
修改多个文件的权限为755,添加release.sh和docker-env.sh脚本,配置Gitea的CI工作流和版本更新日志配置文件
2025-04-16 15:47:06 +08:00

167 lines
5.1 KiB
PHP
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* hyperf_admin 鉴权中间件
* 统一负责 资源权限校验
*/
namespace HyperfAdmin\Admin\Middleware;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Contract\ResponseInterface as HttpResponse;
use Hyperf\HttpServer\CoreMiddleware;
use Hyperf\Logger\LoggerFactory;
use HyperfAdmin\Admin\Service\AuthService;
use HyperfAdmin\Admin\Service\ModuleProxy;
use HyperfAdmin\Admin\Service\PermissionService;
use HyperfAdmin\BaseUtils\AKSK;
use HyperfAdmin\BaseUtils\Constants\ErrorCode;
use HyperfAdmin\BaseUtils\Log;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
class PermissionMiddleware extends CoreMiddleware
{
/**
* @var RequestInterface
*/
protected $request;
/**
* @var HttpResponse
*/
protected $response;
/**
* @var LoggerFactory
*/
protected $log;
/**
* @var PermissionService
*/
protected $permission_service;
/**
* @var AuthService
*/
protected $auth_service;
public function __construct(ContainerInterface $container, HttpResponse $response, RequestInterface $request, LoggerFactory $logger)
{
$this->container = $container;
$this->response = $response;
$this->request = $request;
$this->log = $logger->get('permission');
$this->permission_service = make(PermissionService::class);
$this->auth_service = make(AuthService::class);
parent::__construct($container, 'http');
}
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$uri = $request->getUri();
$path = $uri->getPath();
$method = $request->getMethod();
$module_proxy = make(ModuleProxy::class);
if ($module_proxy->needProxy()) {
$res = $module_proxy->request();
if (isset($res['payload']) && $res['payload'] === []) {
$res['payload'] = (object)[];
}
$response = $this->response->json($res);
Log::get('http')->info('proxy_end', [
'module' => $module_proxy->getTargetModule(),
'path' => $path,
'response' => $response,
]);
return $response;
}
// 其他系统调用走AKSK中间件验证
$client_token = $request->getHeader('Authorization')[0] ?? '';
if ($client_token) {
if (!$this->akSkAuth($uri, $method, $client_token)) {
return $this->fail(ErrorCode::CODE_ERR_DENY, '接口权限校验失败');
}
return $handler->handle($request);
}
// 内部请求时不做鉴权
if ($this->getRealIp() == '127.0.0.1') {
return $handler->handle($request);
}
// 开放资源,不进行鉴权
if ($this->permission_service->isOpen($path, $method)) {
return $handler->handle($request);
}
// 检验登录状态
$user = $this->auth_service->user();
if (empty($user)) {
return $this->fail(ErrorCode::CODE_LOGIN, '请先登录');
}
if (!$this->permission_service->hasPermission($path, $method)) {
return $this->fail(ErrorCode::CODE_NO_AUTH, "{$path}权限不足");
}
return $handler->handle($request);
}
protected function getRealIp()
{
return $this->request->header('x-real-ip');
}
/**
* @param int $code
* @param string|null $message
*
* @return \Psr\Http\Message\ResponseInterface
*/
public function fail(int $code = -1, ?string $message = null)
{
$response = [
'code' => $code,
'message' => $message ?: ErrorCode::getMessage($code),
'payload' => (object)[],
];
$this->log->warning($this->request->getUri()->getPath() . ' fail', $response);
return $this->response->json($response);
}
private function akSkAuth($uri, $method, $client_token)
{
$host = env('APP_DOMAIN', '');
$query = $this->request->getQueryParams();
if (!empty($query)) {
ksort($query);
$query = http_build_query($query);
} else {
$query = '';
}
$path = $uri->getPath();
$content_type = $this->request->getHeader('Content-type')[0] ?? '';
$body = $this->request->getParsedBody();
if (!empty($body)) {
ksort($body);
$body = json_encode($body, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
} else {
$body = '';
}
$ak = str_replace('ha ', '', explode(':', $client_token)[0] ?? '');
$sk = config('client_user')[$ak] ?? '';
$auth = new AKSK($ak, $sk);
$token = $auth->token($method, $path, $host, $query, $content_type, $body);
$this->log->info('aksk auth:', [
'client_token' => $client_token,
'except_token' => $token,
]);
return $token === $client_token;
}
}