From 94584d242b8e47ab7ee531d5f66dbb801be415bf Mon Sep 17 00:00:00 2001 From: geh <1923421292@qq.com> Date: Thu, 19 Mar 2026 18:01:38 +0800 Subject: [PATCH] 1 --- SUBQHSE/FineUIPro.Web/common/PageBase.cs | 98 +++++++++++++++++++++--- 1 file changed, 87 insertions(+), 11 deletions(-) diff --git a/SUBQHSE/FineUIPro.Web/common/PageBase.cs b/SUBQHSE/FineUIPro.Web/common/PageBase.cs index 0bb9fe5..997f7d2 100644 --- a/SUBQHSE/FineUIPro.Web/common/PageBase.cs +++ b/SUBQHSE/FineUIPro.Web/common/PageBase.cs @@ -149,30 +149,64 @@ namespace FineUIPro.Web { try { + // 验证token格式(防止注入攻击) + if (authToken.Length > 500 || System.Text.RegularExpressions.Regex.IsMatch(authToken, @"[^\w\-\.=+/]")) + { + throw new ArgumentException("无效的Token格式"); + } + // 解密并验证token string decryptedToken = BLL.TokenHelper.DecryptToken(authToken); + if (string.IsNullOrEmpty(decryptedToken)) + { + throw new InvalidOperationException("Token解密失败"); + } + var tokenData = JsonConvert.DeserializeObject(decryptedToken); + if (tokenData == null) + { + throw new InvalidOperationException("Token解析失败"); + } // 验证时间戳(2小时有效期) long timestamp = tokenData.timestamp; - if (DateTimeOffset.Now.ToUnixTimeSeconds() - timestamp <= 7200) // 2小时 = 7200秒 + long currentTime = DateTimeOffset.Now.ToUnixTimeSeconds(); + if (currentTime - timestamp > 7200) // 2小时 = 7200秒 { - // 验证用户ID - string userId = tokenData.user_id; - if (userId == Const.sysglyId) + throw new InvalidOperationException("Token已过期"); + } + if (timestamp > currentTime + 300) // 允许5分钟时钟偏差 + { + throw new InvalidOperationException("Token时间戳无效"); + } + + // 验证用户ID + string userId = tokenData.user_id; + if (!string.IsNullOrEmpty(userId)) + { + // 移除硬编码限制,支持任意用户通过token登录 + var user = UserService.GetUserByUserId(userId); + if (user != null) { - var user = UserService.GetUserByUserId(Const.sysglyId); - if (user != null) - { - this.Session["CurrUser"] = user; - BLL.LogService.AddLog(Const.sysglyId, "iframe Token自动登录成功"); - } + // 验证用户状态(如果用户表有状态字段) + this.Session["CurrUser"] = user; + BLL.LogService.AddLog(userId, $"iframe Token自动登录成功 - IP: {GetClientIP()}"); } + else + { + throw new InvalidOperationException($"用户不存在: {userId}"); + } + } + else + { + throw new ArgumentException("Token中缺少user_id"); } } catch (Exception ex) { - BLL.LogService.AddLog("", $"iframe Token自动登录失败:{ex.Message}"); + // 记录详细的安全日志 + BLL.LogService.AddLog("", $"iframe Token自动登录失败 [{ex.GetType().Name}]: {ex.Message} - IP: {GetClientIP()}"); + // Token验证失败,继续正常的登录流程 } } string httpRefere = Request.ServerVariables["HTTP_REFERER"]; @@ -1236,5 +1270,47 @@ namespace FineUIPro.Web return table; } + + /// + /// 获取客户端真实IP地址(考虑代理和负载均衡) + /// + /// 客户端IP地址 + protected string GetClientIP() + { + string ip = string.Empty; + + // 检查 X-Forwarded-For 头(代理和负载均衡) + if (System.Web.HttpContext.Current.Request.Headers["X-Forwarded-For"] != null) + { + ip = System.Web.HttpContext.Current.Request.Headers["X-Forwarded-For"].Split(',')[0].Trim(); + } + // 检查 X-Real-IP 头(Nginx代理) + else if (System.Web.HttpContext.Current.Request.Headers["X-Real-IP"] != null) + { + ip = System.Web.HttpContext.Current.Request.Headers["X-Real-IP"]; + } + // 检查 CF-Connecting-IP 头(Cloudflare) + else if (System.Web.HttpContext.Current.Request.Headers["CF-Connecting-IP"] != null) + { + ip = System.Web.HttpContext.Current.Request.Headers["CF-Connecting-IP"]; + } + // 使用直接连接的IP + else if (System.Web.HttpContext.Current.Request.Headers["HTTP_X_FORWARDED_FOR"] != null) + { + ip = System.Web.HttpContext.Current.Request.Headers["HTTP_X_FORWARDED_FOR"]; + } + else + { + ip = System.Web.HttpContext.Current.Request.UserHostAddress; + } + + // 验证IP格式 + if (string.IsNullOrEmpty(ip) || ip.Length > 45) + { + ip = "Unknown"; + } + + return ip; + } } } \ No newline at end of file