900 lines
29 KiB
Python
900 lines
29 KiB
Python
"""
|
||
认证管理器模块
|
||
确保通信安全
|
||
"""
|
||
|
||
import time
|
||
import hashlib
|
||
import secrets
|
||
import hmac
|
||
from typing import Dict, Any, List, Optional
|
||
|
||
class AuthManager:
|
||
"""
|
||
认证管理器
|
||
确保通信安全
|
||
"""
|
||
|
||
def __init__(self, plugin):
|
||
"""
|
||
初始化认证管理器
|
||
|
||
Args:
|
||
plugin: 实时通信插件实例
|
||
"""
|
||
self.plugin = plugin
|
||
self.enabled = False
|
||
self.initialized = False
|
||
|
||
# 认证配置
|
||
self.auth_config = {
|
||
"enable_authentication": True,
|
||
"auth_timeout": 30.0,
|
||
"enable_token_auth": True,
|
||
"enable_password_auth": True,
|
||
"token_lifetime": 86400, # 24小时
|
||
"enable_session_management": True,
|
||
"session_timeout": 3600, # 1小时
|
||
"enable_two_factor_auth": False,
|
||
"max_login_attempts": 5,
|
||
"login_lockout_duration": 900, # 15分钟
|
||
"enable_ip_filtering": True,
|
||
"enable_audit_logging": True
|
||
}
|
||
|
||
# 认证状态
|
||
self.auth_state = {
|
||
"active_sessions": 0,
|
||
"total_authentications": 0,
|
||
"successful_authentications": 0,
|
||
"failed_authentications": 0
|
||
}
|
||
|
||
# 认证存储
|
||
self.sessions = {}
|
||
self.tokens = {}
|
||
self.login_attempts = {}
|
||
self.blocked_ips = {}
|
||
|
||
# 认证统计
|
||
self.auth_stats = {
|
||
"tokens_generated": 0,
|
||
"sessions_created": 0,
|
||
"sessions_expired": 0,
|
||
"users_banned": 0,
|
||
"auth_errors": 0
|
||
}
|
||
|
||
# 密钥管理
|
||
self.secret_key = self._generate_secret_key()
|
||
|
||
# 回调函数
|
||
self.auth_callbacks = {
|
||
"auth_success": [],
|
||
"auth_failed": [],
|
||
"session_created": [],
|
||
"session_expired": [],
|
||
"user_banned": [],
|
||
"auth_error": []
|
||
}
|
||
|
||
# 时间戳记录
|
||
self.last_session_cleanup = 0.0
|
||
self.last_auth_event = 0.0
|
||
|
||
print("✓ 认证管理器已创建")
|
||
|
||
def initialize(self) -> bool:
|
||
"""
|
||
初始化认证管理器
|
||
|
||
Returns:
|
||
是否初始化成功
|
||
"""
|
||
try:
|
||
print("正在初始化认证管理器...")
|
||
|
||
# 生成密钥
|
||
self.secret_key = self._generate_secret_key()
|
||
|
||
self.initialized = True
|
||
print("✓ 认证管理器初始化完成")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 认证管理器初始化失败: {e}")
|
||
self.auth_stats["auth_errors"] += 1
|
||
import traceback
|
||
traceback.print_exc()
|
||
return False
|
||
|
||
def _generate_secret_key(self) -> str:
|
||
"""
|
||
生成密钥
|
||
|
||
Returns:
|
||
生成的密钥
|
||
"""
|
||
try:
|
||
return secrets.token_hex(32)
|
||
except Exception as e:
|
||
print(f"✗ 密钥生成失败: {e}")
|
||
# 使用默认密钥(仅用于开发环境)
|
||
return "default_secret_key_for_development_purposes_only"
|
||
|
||
def enable(self) -> bool:
|
||
"""
|
||
启用认证管理器
|
||
|
||
Returns:
|
||
是否启用成功
|
||
"""
|
||
try:
|
||
if not self.initialized:
|
||
print("✗ 认证管理器未初始化")
|
||
return False
|
||
|
||
self.enabled = True
|
||
print("✓ 认证管理器已启用")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 认证管理器启用失败: {e}")
|
||
self.auth_stats["auth_errors"] += 1
|
||
import traceback
|
||
traceback.print_exc()
|
||
return False
|
||
|
||
def disable(self):
|
||
"""禁用认证管理器"""
|
||
try:
|
||
self.enabled = False
|
||
|
||
# 清理会话和令牌
|
||
self.sessions.clear()
|
||
self.tokens.clear()
|
||
|
||
print("✓ 认证管理器已禁用")
|
||
|
||
except Exception as e:
|
||
print(f"✗ 认证管理器禁用失败: {e}")
|
||
self.auth_stats["auth_errors"] += 1
|
||
import traceback
|
||
traceback.print_exc()
|
||
|
||
def finalize(self):
|
||
"""清理认证管理器资源"""
|
||
try:
|
||
# 禁用认证管理器
|
||
if self.enabled:
|
||
self.disable()
|
||
|
||
# 清理回调
|
||
self.auth_callbacks.clear()
|
||
|
||
self.initialized = False
|
||
print("✓ 认证管理器资源已清理")
|
||
|
||
except Exception as e:
|
||
print(f"✗ 认证管理器资源清理失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
|
||
def update(self, dt: float):
|
||
"""
|
||
更新认证管理器状态
|
||
|
||
Args:
|
||
dt: 时间增量(秒)
|
||
"""
|
||
try:
|
||
if not self.enabled:
|
||
return
|
||
|
||
current_time = time.time()
|
||
|
||
# 定期清理过期会话
|
||
if current_time - self.last_session_cleanup > 300: # 每5分钟清理一次
|
||
self._cleanup_expired_sessions(current_time)
|
||
self.last_session_cleanup = current_time
|
||
|
||
# 定期清理登录尝试记录
|
||
self._cleanup_login_attempts(current_time)
|
||
|
||
self.last_auth_event = current_time
|
||
|
||
except Exception as e:
|
||
print(f"✗ 认证管理器更新失败: {e}")
|
||
self.auth_stats["auth_errors"] += 1
|
||
import traceback
|
||
traceback.print_exc()
|
||
|
||
def _cleanup_expired_sessions(self, current_time: float):
|
||
"""清理过期会话"""
|
||
try:
|
||
expired_sessions = []
|
||
for session_id, session_data in self.sessions.items():
|
||
if current_time - session_data["login_time"] > self.auth_config["session_timeout"]:
|
||
expired_sessions.append(session_id)
|
||
|
||
for session_id in expired_sessions:
|
||
del self.sessions[session_id]
|
||
self.auth_state["active_sessions"] -= 1
|
||
self.auth_stats["sessions_expired"] += 1
|
||
|
||
# 触发会话过期回调
|
||
self._trigger_auth_callback("session_expired", {
|
||
"session_id": session_id,
|
||
"timestamp": current_time
|
||
})
|
||
|
||
except Exception as e:
|
||
print(f"✗ 过期会话清理失败: {e}")
|
||
self.auth_stats["auth_errors"] += 1
|
||
|
||
def _cleanup_login_attempts(self, current_time: float):
|
||
"""清理登录尝试记录"""
|
||
try:
|
||
expired_attempts = []
|
||
for ip_address, attempt_data in self.login_attempts.items():
|
||
if current_time - attempt_data["last_attempt"] > self.auth_config["login_lockout_duration"]:
|
||
expired_attempts.append(ip_address)
|
||
|
||
for ip_address in expired_attempts:
|
||
del self.login_attempts[ip_address]
|
||
|
||
except Exception as e:
|
||
print(f"✗ 登录尝试记录清理失败: {e}")
|
||
self.auth_stats["auth_errors"] += 1
|
||
|
||
def authenticate_client(self, client_id: str, auth_data: Dict[str, Any]) -> bool:
|
||
"""
|
||
认证客户端
|
||
|
||
Args:
|
||
client_id: 客户端ID
|
||
auth_data: 认证数据
|
||
|
||
Returns:
|
||
是否认证成功
|
||
"""
|
||
try:
|
||
if not self.enabled or not self.auth_config["enable_authentication"]:
|
||
# 如果未启用认证,直接通过
|
||
return True
|
||
|
||
# 检查IP是否被阻止
|
||
client_ip = auth_data.get("client_ip", "")
|
||
if self._is_ip_blocked(client_ip):
|
||
self.auth_stats["failed_authentications"] += 1
|
||
return False
|
||
|
||
# 检查登录尝试次数
|
||
if self._is_login_blocked(client_ip):
|
||
self.auth_stats["failed_authentications"] += 1
|
||
return False
|
||
|
||
# 执行认证
|
||
auth_result = self._perform_authentication(client_id, auth_data)
|
||
|
||
if auth_result:
|
||
self.auth_state["successful_authentications"] += 1
|
||
self.auth_state["total_authentications"] += 1
|
||
|
||
# 触发认证成功回调
|
||
self._trigger_auth_callback("auth_success", {
|
||
"client_id": client_id,
|
||
"auth_data": auth_data,
|
||
"timestamp": time.time()
|
||
})
|
||
|
||
# 记录审计日志
|
||
if self.auth_config["enable_audit_logging"]:
|
||
self._log_auth_event("auth_success", client_id, client_ip)
|
||
|
||
else:
|
||
self.auth_state["failed_authentications"] += 1
|
||
self.auth_state["total_authentications"] += 1
|
||
|
||
# 记录失败的登录尝试
|
||
self._record_failed_login(client_ip)
|
||
|
||
# 触发认证失败回调
|
||
self._trigger_auth_callback("auth_failed", {
|
||
"client_id": client_id,
|
||
"auth_data": auth_data,
|
||
"timestamp": time.time()
|
||
})
|
||
|
||
# 记录审计日志
|
||
if self.auth_config["enable_audit_logging"]:
|
||
self._log_auth_event("auth_failed", client_id, client_ip)
|
||
|
||
return auth_result
|
||
|
||
except Exception as e:
|
||
print(f"✗ 客户端认证失败: {e}")
|
||
self.auth_stats["auth_errors"] += 1
|
||
return False
|
||
|
||
def _is_ip_blocked(self, client_ip: str) -> bool:
|
||
"""
|
||
检查IP是否被阻止
|
||
|
||
Args:
|
||
client_ip: 客户端IP
|
||
|
||
Returns:
|
||
IP是否被阻止
|
||
"""
|
||
try:
|
||
if not self.auth_config["enable_ip_filtering"]:
|
||
return False
|
||
|
||
if client_ip in self.blocked_ips:
|
||
block_data = self.blocked_ips[client_ip]
|
||
if time.time() - block_data["block_time"] < block_data["duration"]:
|
||
return True
|
||
else:
|
||
# 阻止时间已过期,移除
|
||
del self.blocked_ips[client_ip]
|
||
|
||
return False
|
||
|
||
except Exception as e:
|
||
print(f"✗ IP阻止检查失败: {e}")
|
||
self.auth_stats["auth_errors"] += 1
|
||
return False
|
||
|
||
def _is_login_blocked(self, client_ip: str) -> bool:
|
||
"""
|
||
检查登录是否被阻止
|
||
|
||
Args:
|
||
client_ip: 客户端IP
|
||
|
||
Returns:
|
||
登录是否被阻止
|
||
"""
|
||
try:
|
||
if client_ip in self.login_attempts:
|
||
attempts = self.login_attempts[client_ip]
|
||
if (attempts["count"] >= self.auth_config["max_login_attempts"] and
|
||
time.time() - attempts["last_attempt"] < self.auth_config["login_lockout_duration"]):
|
||
return True
|
||
|
||
return False
|
||
|
||
except Exception as e:
|
||
print(f"✗ 登录阻止检查失败: {e}")
|
||
self.auth_stats["auth_errors"] += 1
|
||
return False
|
||
|
||
def _record_failed_login(self, client_ip: str):
|
||
"""
|
||
记录失败的登录尝试
|
||
|
||
Args:
|
||
client_ip: 客户端IP
|
||
"""
|
||
try:
|
||
current_time = time.time()
|
||
|
||
if client_ip not in self.login_attempts:
|
||
self.login_attempts[client_ip] = {
|
||
"count": 1,
|
||
"last_attempt": current_time
|
||
}
|
||
else:
|
||
self.login_attempts[client_ip]["count"] += 1
|
||
self.login_attempts[client_ip]["last_attempt"] = current_time
|
||
|
||
# 如果超过最大尝试次数,阻止IP
|
||
if (self.login_attempts[client_ip]["count"] >=
|
||
self.auth_config["max_login_attempts"]):
|
||
self._block_ip(client_ip, self.auth_config["login_lockout_duration"])
|
||
|
||
except Exception as e:
|
||
print(f"✗ 失败登录记录失败: {e}")
|
||
self.auth_stats["auth_errors"] += 1
|
||
|
||
def _perform_authentication(self, client_id: str, auth_data: Dict[str, Any]) -> bool:
|
||
"""
|
||
执行认证
|
||
|
||
Args:
|
||
client_id: 客户端ID
|
||
auth_data: 认证数据
|
||
|
||
Returns:
|
||
是否认证成功
|
||
"""
|
||
try:
|
||
# 检查认证类型
|
||
auth_type = auth_data.get("auth_type", "token")
|
||
|
||
if auth_type == "token":
|
||
return self._authenticate_with_token(client_id, auth_data)
|
||
elif auth_type == "password":
|
||
return self._authenticate_with_password(client_id, auth_data)
|
||
elif auth_type == "session":
|
||
return self._authenticate_with_session(client_id, auth_data)
|
||
else:
|
||
# 默认认证方式
|
||
return self._authenticate_with_token(client_id, auth_data)
|
||
|
||
except Exception as e:
|
||
print(f"✗ 认证执行失败: {e}")
|
||
self.auth_stats["auth_errors"] += 1
|
||
return False
|
||
|
||
def _authenticate_with_token(self, client_id: str, auth_data: Dict[str, Any]) -> bool:
|
||
"""
|
||
使用令牌认证
|
||
|
||
Args:
|
||
client_id: 客户端ID
|
||
auth_data: 认证数据
|
||
|
||
Returns:
|
||
是否认证成功
|
||
"""
|
||
try:
|
||
token = auth_data.get("token")
|
||
if not token:
|
||
return False
|
||
|
||
# 验证令牌
|
||
if token in self.tokens:
|
||
token_data = self.tokens[token]
|
||
if time.time() - token_data["created_time"] < self.auth_config["token_lifetime"]:
|
||
# 令牌有效,创建会话
|
||
self._create_session(client_id, auth_data)
|
||
return True
|
||
else:
|
||
# 令牌过期,移除
|
||
del self.tokens[token]
|
||
|
||
return False
|
||
|
||
except Exception as e:
|
||
print(f"✗ 令牌认证失败: {e}")
|
||
self.auth_stats["auth_errors"] += 1
|
||
return False
|
||
|
||
def _authenticate_with_password(self, client_id: str, auth_data: Dict[str, Any]) -> bool:
|
||
"""
|
||
使用密码认证
|
||
|
||
Args:
|
||
client_id: 客户端ID
|
||
auth_data: 认证数据
|
||
|
||
Returns:
|
||
是否认证成功
|
||
"""
|
||
try:
|
||
username = auth_data.get("username")
|
||
password = auth_data.get("password")
|
||
|
||
if not username or not password:
|
||
return False
|
||
|
||
# 验证密码(简化实现)
|
||
# 在实际应用中,这里应该连接到用户数据库验证用户名和密码
|
||
if username == "test_user" and password == "test_password":
|
||
# 创建会话
|
||
self._create_session(client_id, auth_data)
|
||
return True
|
||
else:
|
||
return False
|
||
|
||
except Exception as e:
|
||
print(f"✗ 密码认证失败: {e}")
|
||
self.auth_stats["auth_errors"] += 1
|
||
return False
|
||
|
||
def _authenticate_with_session(self, client_id: str, auth_data: Dict[str, Any]) -> bool:
|
||
"""
|
||
使用会话认证
|
||
|
||
Args:
|
||
client_id: 客户端ID
|
||
auth_data: 认证数据
|
||
|
||
Returns:
|
||
是否认证成功
|
||
"""
|
||
try:
|
||
session_id = auth_data.get("session_id")
|
||
if not session_id:
|
||
return False
|
||
|
||
# 检查会话是否存在且有效
|
||
if session_id in self.sessions:
|
||
session_data = self.sessions[session_id]
|
||
if time.time() - session_data["login_time"] < self.auth_config["session_timeout"]:
|
||
# 更新会话最后活动时间
|
||
session_data["last_activity"] = time.time()
|
||
return True
|
||
|
||
return False
|
||
|
||
except Exception as e:
|
||
print(f"✗ 会话认证失败: {e}")
|
||
self.auth_stats["auth_errors"] += 1
|
||
return False
|
||
|
||
def _create_session(self, client_id: str, auth_data: Dict[str, Any]):
|
||
"""
|
||
创建会话
|
||
|
||
Args:
|
||
client_id: 客户端ID
|
||
auth_data: 认证数据
|
||
"""
|
||
try:
|
||
session_id = self._generate_session_id()
|
||
|
||
session_data = {
|
||
"client_id": client_id,
|
||
"login_time": time.time(),
|
||
"last_activity": time.time(),
|
||
"user_id": auth_data.get("user_id", ""),
|
||
"username": auth_data.get("username", ""),
|
||
"permissions": auth_data.get("permissions", [])
|
||
}
|
||
|
||
self.sessions[session_id] = session_data
|
||
self.auth_state["active_sessions"] += 1
|
||
self.auth_stats["sessions_created"] += 1
|
||
|
||
# 触发会话创建回调
|
||
self._trigger_auth_callback("session_created", {
|
||
"session_id": session_id,
|
||
"client_id": client_id,
|
||
"auth_data": auth_data,
|
||
"timestamp": time.time()
|
||
})
|
||
|
||
except Exception as e:
|
||
print(f"✗ 会话创建失败: {e}")
|
||
self.auth_stats["auth_errors"] += 1
|
||
|
||
def _generate_session_id(self) -> str:
|
||
"""
|
||
生成会话ID
|
||
|
||
Returns:
|
||
生成的会话ID
|
||
"""
|
||
try:
|
||
return secrets.token_urlsafe(32)
|
||
except Exception as e:
|
||
print(f"✗ 会话ID生成失败: {e}")
|
||
self.auth_stats["auth_errors"] += 1
|
||
return f"session_{int(time.time() * 1000000)}"
|
||
|
||
def generate_token(self, user_id: str, permissions: List[str] = None) -> str:
|
||
"""
|
||
生成令牌
|
||
|
||
Args:
|
||
user_id: 用户ID
|
||
permissions: 权限列表
|
||
|
||
Returns:
|
||
生成的令牌
|
||
"""
|
||
try:
|
||
token = secrets.token_urlsafe(64)
|
||
|
||
self.tokens[token] = {
|
||
"user_id": user_id,
|
||
"permissions": permissions or [],
|
||
"created_time": time.time()
|
||
}
|
||
|
||
self.auth_stats["tokens_generated"] += 1
|
||
|
||
return token
|
||
|
||
except Exception as e:
|
||
print(f"✗ 令牌生成失败: {e}")
|
||
self.auth_stats["auth_errors"] += 1
|
||
return ""
|
||
|
||
def validate_token(self, token: str) -> bool:
|
||
"""
|
||
验证令牌
|
||
|
||
Args:
|
||
token: 令牌
|
||
|
||
Returns:
|
||
令牌是否有效
|
||
"""
|
||
try:
|
||
if not token:
|
||
return False
|
||
|
||
if token in self.tokens:
|
||
token_data = self.tokens[token]
|
||
if time.time() - token_data["created_time"] < self.auth_config["token_lifetime"]:
|
||
return True
|
||
else:
|
||
# 令牌过期,移除
|
||
del self.tokens[token]
|
||
|
||
return False
|
||
|
||
except Exception as e:
|
||
print(f"✗ 令牌验证失败: {e}")
|
||
self.auth_stats["auth_errors"] += 1
|
||
return False
|
||
|
||
def hash_password(self, password: str, salt: str = None) -> Dict[str, str]:
|
||
"""
|
||
哈希密码
|
||
|
||
Args:
|
||
password: 密码
|
||
salt: 盐值(可选)
|
||
|
||
Returns:
|
||
包含哈希值和盐值的字典
|
||
"""
|
||
try:
|
||
if salt is None:
|
||
salt = secrets.token_hex(16)
|
||
|
||
# 使用PBKDF2哈希密码
|
||
password_hash = hashlib.pbkdf2_hmac('sha256', password.encode('utf-8'), salt.encode('utf-8'), 100000)
|
||
return {
|
||
"hash": password_hash.hex(),
|
||
"salt": salt
|
||
}
|
||
|
||
except Exception as e:
|
||
print(f"✗ 密码哈希失败: {e}")
|
||
self.auth_stats["auth_errors"] += 1
|
||
return {}
|
||
|
||
def verify_password(self, password: str, password_hash: str, salt: str) -> bool:
|
||
"""
|
||
验证密码
|
||
|
||
Args:
|
||
password: 密码
|
||
password_hash: 密码哈希值
|
||
salt: 盐值
|
||
|
||
Returns:
|
||
密码是否正确
|
||
"""
|
||
try:
|
||
# 重新哈希密码
|
||
new_hash = hashlib.pbkdf2_hmac('sha256', password.encode('utf-8'), salt.encode('utf-8'), 100000)
|
||
return hmac.compare_digest(new_hash.hex(), password_hash)
|
||
|
||
except Exception as e:
|
||
print(f"✗ 密码验证失败: {e}")
|
||
self.auth_stats["auth_errors"] += 1
|
||
return False
|
||
|
||
def _block_ip(self, client_ip: str, duration: float):
|
||
"""
|
||
阻止IP地址
|
||
|
||
Args:
|
||
client_ip: 客户端IP
|
||
duration: 阻止持续时间(秒)
|
||
"""
|
||
try:
|
||
self.blocked_ips[client_ip] = {
|
||
"block_time": time.time(),
|
||
"duration": duration
|
||
}
|
||
|
||
# 触发用户禁止回调
|
||
self._trigger_auth_callback("user_banned", {
|
||
"ip_address": client_ip,
|
||
"duration": duration,
|
||
"timestamp": time.time()
|
||
})
|
||
|
||
# 记录审计日志
|
||
if self.auth_config["enable_audit_logging"]:
|
||
self._log_auth_event("ip_blocked", None, client_ip)
|
||
|
||
print(f"✓ IP地址已被阻止: {client_ip} (持续 {duration} 秒)")
|
||
|
||
except Exception as e:
|
||
print(f"✗ IP阻止失败: {e}")
|
||
self.auth_stats["auth_errors"] += 1
|
||
|
||
def unblock_ip(self, client_ip: str) -> bool:
|
||
"""
|
||
解除IP阻止
|
||
|
||
Args:
|
||
client_ip: 客户端IP
|
||
|
||
Returns:
|
||
是否解除成功
|
||
"""
|
||
try:
|
||
if client_ip in self.blocked_ips:
|
||
del self.blocked_ips[client_ip]
|
||
print(f"✓ IP地址阻止已解除: {client_ip}")
|
||
return True
|
||
else:
|
||
print(f"✗ IP地址未被阻止: {client_ip}")
|
||
return False
|
||
|
||
except Exception as e:
|
||
print(f"✗ IP阻止解除失败: {e}")
|
||
self.auth_stats["auth_errors"] += 1
|
||
return False
|
||
|
||
def _log_auth_event(self, event_type: str, client_id: str = None, client_ip: str = None):
|
||
"""
|
||
记录认证事件
|
||
|
||
Args:
|
||
event_type: 事件类型
|
||
client_id: 客户端ID(可选)
|
||
client_ip: 客户端IP(可选)
|
||
"""
|
||
try:
|
||
if not self.auth_config["enable_audit_logging"]:
|
||
return
|
||
|
||
event = {
|
||
"event_type": event_type,
|
||
"client_id": client_id,
|
||
"client_ip": client_ip,
|
||
"timestamp": time.time()
|
||
}
|
||
|
||
# 在实际实现中,这里会将事件记录到日志文件或数据库
|
||
print(f"[认证日志] {event_type} - 客户端: {client_id}, IP: {client_ip}")
|
||
|
||
except Exception as e:
|
||
print(f"✗ 认证事件记录失败: {e}")
|
||
self.auth_stats["auth_errors"] += 1
|
||
|
||
def get_active_sessions(self) -> Dict[str, Any]:
|
||
"""
|
||
获取活跃会话
|
||
|
||
Returns:
|
||
活跃会话字典
|
||
"""
|
||
try:
|
||
return self.sessions.copy()
|
||
except Exception as e:
|
||
print(f"✗ 获取活跃会话失败: {e}")
|
||
self.auth_stats["auth_errors"] += 1
|
||
return {}
|
||
|
||
def get_blocked_ips(self) -> Dict[str, Any]:
|
||
"""
|
||
获取被阻止的IP地址
|
||
|
||
Returns:
|
||
被阻止的IP地址字典
|
||
"""
|
||
try:
|
||
return self.blocked_ips.copy()
|
||
except Exception as e:
|
||
print(f"✗ 获取被阻止的IP地址失败: {e}")
|
||
self.auth_stats["auth_errors"] += 1
|
||
return {}
|
||
|
||
def get_auth_stats(self) -> Dict[str, Any]:
|
||
"""
|
||
获取认证统计信息
|
||
|
||
Returns:
|
||
认证统计字典
|
||
"""
|
||
return {
|
||
"state": self.auth_state.copy(),
|
||
"stats": self.auth_stats.copy(),
|
||
"config": self.auth_config.copy()
|
||
}
|
||
|
||
def reset_stats(self):
|
||
"""重置认证统计信息"""
|
||
try:
|
||
self.auth_stats = {
|
||
"tokens_generated": 0,
|
||
"sessions_created": 0,
|
||
"sessions_expired": 0,
|
||
"users_banned": 0,
|
||
"auth_errors": 0
|
||
}
|
||
print("✓ 认证统计信息已重置")
|
||
except Exception as e:
|
||
print(f"✗ 认证统计信息重置失败: {e}")
|
||
|
||
def set_auth_config(self, config: Dict[str, Any]) -> bool:
|
||
"""
|
||
设置认证配置
|
||
|
||
Args:
|
||
config: 认证配置字典
|
||
|
||
Returns:
|
||
是否设置成功
|
||
"""
|
||
try:
|
||
self.auth_config.update(config)
|
||
print(f"✓ 认证配置已更新: {self.auth_config}")
|
||
return True
|
||
except Exception as e:
|
||
print(f"✗ 认证配置设置失败: {e}")
|
||
return False
|
||
|
||
def get_auth_config(self) -> Dict[str, Any]:
|
||
"""
|
||
获取认证配置
|
||
|
||
Returns:
|
||
认证配置字典
|
||
"""
|
||
return self.auth_config.copy()
|
||
|
||
def _trigger_auth_callback(self, callback_type: str, data: Dict[str, Any]):
|
||
"""
|
||
触发认证回调
|
||
|
||
Args:
|
||
callback_type: 回调类型
|
||
data: 回调数据
|
||
"""
|
||
try:
|
||
if callback_type in self.auth_callbacks:
|
||
for callback in self.auth_callbacks[callback_type]:
|
||
try:
|
||
callback(data)
|
||
except Exception as e:
|
||
print(f"✗ 认证回调执行失败: {callback_type} - {e}")
|
||
except Exception as e:
|
||
print(f"✗ 认证回调触发失败: {e}")
|
||
|
||
def register_auth_callback(self, callback_type: str, callback: callable):
|
||
"""
|
||
注册认证回调
|
||
|
||
Args:
|
||
callback_type: 回调类型
|
||
callback: 回调函数
|
||
"""
|
||
try:
|
||
if callback_type in self.auth_callbacks:
|
||
self.auth_callbacks[callback_type].append(callback)
|
||
print(f"✓ 认证回调已注册: {callback_type}")
|
||
else:
|
||
print(f"✗ 无效的回调类型: {callback_type}")
|
||
except Exception as e:
|
||
print(f"✗ 认证回调注册失败: {e}")
|
||
|
||
def unregister_auth_callback(self, callback_type: str, callback: callable):
|
||
"""
|
||
注销认证回调
|
||
|
||
Args:
|
||
callback_type: 回调类型
|
||
callback: 回调函数
|
||
"""
|
||
try:
|
||
if callback_type in self.auth_callbacks:
|
||
if callback in self.auth_callbacks[callback_type]:
|
||
self.auth_callbacks[callback_type].remove(callback)
|
||
print(f"✓ 认证回调已注销: {callback_type}")
|
||
else:
|
||
print(f"✗ 无效的回调类型: {callback_type}")
|
||
except Exception as e:
|
||
print(f"✗ 认证回调注销失败: {e}") |