using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using CoreAgent.ProtocolClient.Models; using Microsoft.Extensions.Logging; using Newtonsoft.Json.Linq; namespace CoreAgent.ProtocolClient.ProtocolEngineCore { /// /// 管理客户端的认证过程 /// 职责: /// 1. 处理 "authenticate" 消息响应。 /// 2. 根据服务器的 challenge 发起认证请求。 /// 3. 维护和提供认证状态 (IsAuthenticated)。 /// 4. 在认证成功后触发事件通知。 /// public class AuthenticationManager { private readonly ProtocolClientConfig _config; private readonly ILogger _logger; private readonly Action _sendMessage; private bool _isAuthenticated = false; public bool IsAuthenticated => _isAuthenticated; public event EventHandler? Authenticated; public AuthenticationManager(ProtocolClientConfig config, ILogger logger, Action sendMessage) { _config = config; _logger = logger; _sendMessage = sendMessage; } /// /// 处理收到的认证相关消息。 /// public void HandleMessage(JObject message) { var messageType = message["message"]?.ToString(); if (messageType != "authenticate" && messageType != "ready") { return; } if (_isAuthenticated) return; switch (messageType) { case "authenticate": if (message["ready"]?.Value() == true) { OnAuthenticationSuccess(); } else if (message["error"] == null && !string.IsNullOrEmpty(_config.Password)) { var challenge = message["challenge"]?.ToString() ?? ""; PerformAuthentication(challenge); } else { _logger.LogError($"[{_config.Name}] 认证失败: {message["error"]}"); } break; case "ready": _logger.LogInformation($"[{_config.Name}] 直接收到ready消息,视为认证成功"); OnAuthenticationSuccess(); break; } } /// /// 当收到 "ready" 消息或认证成功时调用,标记为已认证并触发事件。 /// public void HandleReadyMessage() { if (!_isAuthenticated) { _logger.LogInformation($"[{_config.Name}] 收到 ready 消息,完成认证"); OnAuthenticationSuccess(); } } private void PerformAuthentication(string challenge) { var authMessage = new JObject { ["message"] = "authenticate", ["password"] = _config.Password, ["challenge"] = challenge }; _sendMessage(authMessage); } private void OnAuthenticationSuccess() { _logger.LogInformation($"[{_config.Name}] 认证成功"); _isAuthenticated = true; Authenticated?.Invoke(this, EventArgs.Empty); } public void Reset() { _isAuthenticated = false; } } }