PHP零信任架构与身份验证
PHP零信任架构与身份验证
零信任架构的核心思想是不信任任何请求,每个访问请求都要验证身份和权限。今天说说PHP中零信任架构的实现。
零信任的基本原则包括始终验证、最小权限和假设已攻破。
```php
class ZeroTrustAuth
{
private Redis $redis;
public function __construct(Redis $redis)
{
$this->redis = $redis;
}
public function authenticate(string $token, string $resource, string $action): array
{
// 1. 验证令牌
$session = $this->validateToken($token);
if ($session === null) {
return ['allowed' => false, 'reason' => '无效令牌'];
}
// 2. 验证设备指纹
if (!$this->verifyDeviceFingerprint($session['user_id'])) {
return ['allowed' => false, 'reason' => '设备指纹不匹配'];
}
// 3. 验证地理位置
if (!$this->verifyLocation($session['user_id'])) {
return ['allowed' => false, 'reason' => '地理位置异常'];
}
// 4. 验证权限
if (!$this->checkPermission($session['user_id'], $resource, $action)) {
return ['allowed' => false, 'reason' => '权限不足'];
}
// 5. 验证行为风险
$riskScore = $this->assessRisk($session['user_id'], $resource, $action);
if ($riskScore > 80) {
return ['allowed' => false, 'reason' => '高风险行为'];
}
// 6. 持续验证
$this->updateSession($session);
return [
'allowed' => true,
'risk_score' => $riskScore,
'session' => $session,
];
}
private function validateToken(string $token): ?array
{
$session = $this->redis->get("session:{$token}");
if ($session === false) return null;
$data = json_decode($session, true);
if ($data['expires'] < time()) return null;
return $data;
}
private function verifyDeviceFingerprint(int $userId): bool
{
$expected = $this->redis->get("device:{$userId}");
$actual = $this->getDeviceFingerprint();
return $expected === false || hash_equals($expected, $actual);
}
private function verifyLocation(int $userId): bool
{
$lastLocation = $this->redis->get("location:{$userId}");
$currentLocation = $_SERVER['REMOTE_ADDR'] ?? '';
if ($lastLocation && $currentLocation) {
// 检查地理位置突变
}
return true;
}
private function checkPermission(int $userId, string $resource, string $action): bool
{
$permissions = $this->redis->sMembers("perms:{$userId}");
return in_array("{$resource}:{$action}", $permissions);
}
private function assessRisk(int $userId, string $resource, string $action): int
{
$key = "risk:{$userId}:{$resource}";
$recentAccess = (int)$this->redis->get($key);
$this->redis->setex($key, 300, $recentAccess + 1);
return min(100, $recentAccess * 10);
}
private function getDeviceFingerprint(): string
{
return hash('sha256', json_encode([
'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '',
'accept' => $_SERVER['HTTP_ACCEPT'] ?? '',
'encoding' => $_SERVER['HTTP_ACCEPT_ENCODING'] ?? '',
'language' => $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? '',
]));
}
private function updateSession(array $session): void
{
$session['last_access'] = time();
$this->redis->setex(
"session:{$session['token']}",
3600,
json_encode($session)
);
}
}
?>
零信任的持续验证和最小权限实现:
```php
class ContinuousVerification
{
private Redis $redis;
public function __construct(Redis $redis)
{
$this->redis = $redis;
}
public function checkSessionHealth(string $token): bool
{
$session = $this->redis->get("session:{$token}");
if ($session === false) return false;
$data = json_decode($session, true);
// 检查会话时长
if ($data['created'] + 3600 < time()) {
$this->forceReauth($token);
return false;
}
// 检查不活动超时
if ($data['last_access'] + 900 < time()) {
$this->forceReauth($token);
return false;
}
return true;
}
private function forceReauth(string $token): void
{
$this->redis->del("session:{$token}");
}
}
class MinimumPrivilege
{
private array $rolePermissions;
public function __construct()
{
$this->rolePermissions = [
'viewer' => ['read'],
'editor' => ['read', 'create', 'update'],
'admin' => ['read', 'create', 'update', 'delete', 'manage'],
];
}
public function hasPermission(string $role, string $action): bool
{
$permissions = $this->rolePermissions[$role] ?? [];
return in_array($action, $permissions);
}
public function getEffectivePermissions(string $role): array
{
return $this->rolePermissions[$role] ?? [];
}
public function generateToken(string $userId, string $role, int $ttl = 3600): string
{
$token = bin2hex(random_bytes(32));
$session = [
'user_id' => $userId,
'role' => $role,
'permissions' => $this->getEffectivePermissions($role),
'created' => time(),
'expires' => time() + $ttl,
'token' => $token,
];
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->setex("session:{$token}", $ttl, json_encode($session));
return $token;
}
}
?>
零信任架构强调持续验证。不仅仅是登录时验证,每次请求都需要验证身份、设备和权限。最小权限原则确保用户只拥有完成任务所需的最小权限。假设已攻破原则要求系统在部分被攻破时仍能保护核心数据。
