PHP 怎么PHP 白名单授权

wen PHP项目 2

本文目录导读:

PHP 怎么PHP 白名单授权

  1. IP 白名单授权
  2. API 密钥白名单
  3. 数据库驱动的用户白名单
  4. 配置文件白名单
  5. 中间件形式的白名单授权
  6. 完整示例:多因素白名单授权系统
  7. 最佳实践建议

在 PHP 中实现白名单授权,通常用于限制某些操作、IP 地址、API 访问或用户权限,以下是几种常见的白名单授权实现方式:

IP 白名单授权

基本 IP 白名单

<?php
class IPWhitelist {
    private $whitelist = [
        '192.168.1.100',
        '10.0.0.1',
        '127.0.0.1'
    ];
    public function checkIP($ip = null) {
        if ($ip === null) {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
        if (in_array($ip, $this->whitelist)) {
            return true;
        }
        // 支持 CIDR 格式
        foreach ($this->whitelist as $allowed) {
            if (strpos($allowed, '/') !== false) {
                if ($this->ipInCIDR($ip, $allowed)) {
                    return true;
                }
            }
        }
        return false;
    }
    private function ipInCIDR($ip, $cidr) {
        list($subnet, $bits) = explode('/', $cidr);
        $ip = ip2long($ip);
        $subnet = ip2long($subnet);
        $mask = -1 << (32 - $bits);
        $subnet &= $mask;
        return ($ip & $mask) === $subnet;
    }
}
// 使用示例
$whitelist = new IPWhitelist();
if (!$whitelist->checkIP()) {
    header('HTTP/1.1 403 Forbidden');
    die('Access denied');
}

API 密钥白名单

<?php
class APIKeyAuth {
    private $apiKeys = [
        'key_1234567890' => [
            'name' => 'Application A',
            'permissions' => ['read', 'write']
        ],
        'key_0987654321' => [
            'name' => 'Application B',
            'permissions' => ['read']
        ]
    ];
    public function authenticate($apiKey) {
        if (isset($this->apiKeys[$apiKey])) {
            $_SESSION['api_client'] = $this->apiKeys[$apiKey];
            return true;
        }
        return false;
    }
    public function checkPermission($permission) {
        if (!isset($_SESSION['api_client'])) {
            return false;
        }
        return in_array($permission, $_SESSION['api_client']['permissions']);
    }
}
// 使用示例
$auth = new APIKeyAuth();
$apiKey = $_GET['api_key'] ?? $_SERVER['HTTP_X_API_KEY'] ?? null;
if (!$apiKey || !$auth->authenticate($apiKey)) {
    header('HTTP/1.1 401 Unauthorized');
    echo json_encode(['error' => 'Invalid API key']);
    exit;
}

数据库驱动的用户白名单

<?php
class UserWhitelist {
    private $db;
    public function __construct($dbConnection) {
        $this->db = $dbConnection;
    }
    public function isUserAuthorized($userId, $resource) {
        $stmt = $this->db->prepare("
            SELECT 1 FROM user_whitelist 
            WHERE user_id = ? AND resource = ? AND status = 'active'
            LIMIT 1
        ");
        $stmt->execute([$userId, $resource]);
        return $stmt->fetchColumn() !== false;
    }
    public function addToWhitelist($userId, $resource) {
        $stmt = $this->db->prepare("
            INSERT INTO user_whitelist (user_id, resource, status, created_at) 
            VALUES (?, ?, 'active', NOW())
            ON DUPLICATE KEY UPDATE status = 'active'
        ");
        return $stmt->execute([$userId, $resource]);
    }
    public function removeFromWhitelist($userId, $resource) {
        $stmt = $this->db->prepare("
            UPDATE user_whitelist 
            SET status = 'removed' 
            WHERE user_id = ? AND resource = ?
        ");
        return $stmt->execute([$userId, $resource]);
    }
}
// 数据库表结构
/*
CREATE TABLE user_whitelist (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT NOT NULL,
    resource VARCHAR(255) NOT NULL,
    status ENUM('active', 'removed') DEFAULT 'active',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    UNIQUE KEY unique_user_resource (user_id, resource)
);
*/

配置文件白名单

<?php
// config/whitelist.php
return [
    'controllers' => [
        'allowed' => [
            'HomeController',
            'UserController',
            'ProductController'
        ],
        'denied' => [
            'AdminController' // 需要额外授权
        ]
    ],
    'actions' => [
        'public' => ['login', 'register', 'forgot_password'],
        'authorized' => ['profile', 'settings', 'orders']
    ],
    'ip_ranges' => [
        '127.0.0.1',
        '192.168.0.0/16',
        '10.0.0.0/8'
    ]
];
// 使用配置文件
class WhitelistManager {
    private $whitelist;
    public function __construct() {
        $this->whitelist = require 'config/whitelist.php';
    }
    public function checkControllerAccess($controller) {
        return in_array($controller, $this->whitelist['controllers']['allowed']);
    }
    public function checkIPAccess($ip) {
        foreach ($this->whitelist['ip_ranges'] as $range) {
            if (strpos($range, '/') !== false) {
                list($subnet, $bits) = explode('/', $range);
                if ($this->ipInRange($ip, $subnet, $bits)) {
                    return true;
                }
            } else if ($ip === $range) {
                return true;
            }
        }
        return false;
    }
    private function ipInRange($ip, $subnet, $bits) {
        $ip = ip2long($ip);
        $subnet = ip2long($subnet);
        $mask = -1 << (32 - $bits);
        $subnet &= $mask;
        return ($ip & $mask) === $subnet;
    }
}

中间件形式的白名单授权

<?php
class WhitelistMiddleware {
    public function handle($request, $next) {
        // 检查 IP 白名单
        if (!$this->checkIPWhitelist()) {
            return $this->denyAccess('IP not authorized');
        }
        // 检查 API 密钥
        if (!$this->checkAPIKey()) {
            return $this->denyAccess('Invalid API key');
        }
        // 检查用户权限
        if (!$this->checkUserPermissions()) {
            return $this->denyAccess('Insufficient permissions');
        }
        return $next($request);
    }
    private function checkIPWhitelist() {
        $whitelist = ['192.168.1.0/24', '10.0.0.1'];
        $clientIP = $_SERVER['REMOTE_ADDR'];
        foreach ($whitelist as $allowed) {
            if (strpos($allowed, '/') !== false) {
                if ($this->ipInCIDR($clientIP, $allowed)) {
                    return true;
                }
            } else if ($clientIP === $allowed) {
                return true;
            }
        }
        return false;
    }
    private function checkAPIKey() {
        $apiKey = $_SERVER['HTTP_X_API_KEY'] ?? null;
        $validKeys = ['prod_key_2024', 'dev_key_2024'];
        return in_array($apiKey, $validKeys);
    }
    private function checkUserPermissions() {
        // 根据具体业务逻辑实现
        return true;
    }
    private function denyAccess($message) {
        header('HTTP/1.1 403 Forbidden');
        echo json_encode(['error' => $message]);
        exit;
    }
}

完整示例:多因素白名单授权系统

<?php
class MultiFactorWhitelist {
    private $rules = [
        'ip' => [
            'whitelist' => ['127.0.0.1', '::1'],
            'strict' => true
        ],
        'time' => [
            'start' => '09:00',
            'end' => '18:00',
            'timezone' => 'Asia/Shanghai'
        ],
        'user_agent' => [
            'allowed' => ['Mozilla/5.0', 'curl/7.68.0'],
            'block_bots' => true
        ],
        'request_rate' => [
            'max_requests' => 100,
            'per_minutes' => 1
        ]
    ];
    public function authorize() {
        // IP 白名单检查
        if ($this->rules['ip']['strict']) {
            if (!$this->checkIP()) {
                return $this->deny('IP not in whitelist');
            }
        }
        // 时间窗口检查
        if (!$this->checkTimeWindow()) {
            return $this->deny('Access outside allowed time');
        }
        // User-Agent 检查
        if (!$this->checkUserAgent()) {
            return $this->deny('Invalid user agent');
        }
        // 请求频率检查
        if (!$this->checkRateLimit()) {
            return $this->deny('Rate limit exceeded');
        }
        return true;
    }
    private function checkIP() {
        $clientIP = $_SERVER['REMOTE_ADDR'];
        return in_array($clientIP, $this->rules['ip']['whitelist']);
    }
    private function checkTimeWindow() {
        $now = new DateTime('now', new DateTimeZone($this->rules['time']['timezone']));
        $start = new DateTime($this->rules['time']['start']);
        $end = new DateTime($this->rules['time']['end']);
        return $now >= $start && $now <= $end;
    }
    private function checkUserAgent() {
        $userAgent = $_SERVER['HTTP_USER_AGENT'] ?? '';
        if ($this->rules['user_agent']['block_bots']) {
            $botPatterns = ['bot', 'crawler', 'spider', 'scrape'];
            foreach ($botPatterns as $pattern) {
                if (stripos($userAgent, $pattern) !== false) {
                    return false;
                }
            }
        }
        if (!empty($this->rules['user_agent']['allowed'])) {
            foreach ($this->rules['user_agent']['allowed'] as $allowed) {
                if (stripos($userAgent, $allowed) !== false) {
                    return true;
                }
            }
            return false;
        }
        return true;
    }
    private function checkRateLimit() {
        // 实现基于 Redis 或文件的速率限制
        return true;
    }
    private function deny($reason) {
        error_log("Access denied: $reason from IP: " . $_SERVER['REMOTE_ADDR']);
        header('HTTP/1.1 403 Forbidden');
        die(json_encode(['error' => 'Access denied']));
    }
}
// 使用示例
$auth = new MultiFactorWhitelist();
$auth->authorize();

最佳实践建议

  1. 安全性考虑

    • 永远不要在客户端存储白名单
    • 使用 HTTPS 传输敏感信息
    • 定期更新和审查白名单
    • 记录所有授权失败的尝试
  2. 性能优化

    • 使用缓存(Redis/Memcached)存储白名单
    • 对于数据库驱动的白名单,确保有适当的索引
    • 考虑使用 Bloom Filter 进行大规模白名单检查
  3. 日志和监控

    • 记录所有授权决策
    • 监控异常访问模式
    • 设置告警机制
  4. 灵活性

    • 支持动态更新白名单而无需重启服务
    • 提供管理界面来管理白名单
    • 支持白名单的分组和继承

根据你的具体需求选择合适的方式,或者组合使用多种方式来实现更完善的白名单授权系统。

抱歉,评论功能暂时关闭!