XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEExtension.NetCore.ServerInteractive

[DLL] Server interaction extension, including user identity verification and querying in conjunction with AutoConfig

公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/XFEExtension.NetCore.ServerInteractive

优化权限校验与日志输出逻辑

- 替换 `ValidatePermission` 方法中 `r.Args.ClientIP` 为 `r.ClientIP`。 - 增强 `XFEDataDictionaryTable` 和 `XFEDataListTable` 的异常处理,捕获 `ServerCoreReturnArgs`。 - 改进 `UserHelper.GetUser` 方法,增加 `session` 校验和日志输出。 - 增加 `IsSameIPAddress` 和 `FormatForLog` 辅助方法。 - 调整多个服务类中 `ClientIP` 的获取方式。 - 更新项目版本号至 `3.1.0`。

78db071
XFE工作室室长 <mail@xfegzs.com>
提交于

代码差异

11 个文件 +139 -39
Modified XFEExtension.NetCore.ServerInteractive.Test/Program.cs +5 -1
@@ -53,7 +53,11 @@ internal class Program
53 53
54 54 private static readonly TableRequester TableRequester = new();
55 55
56 static Program() => s_xFEClientRequester.MessageReceived += XFEClientRequester_MessageReceived;
56 static Program()
57 {
58 s_xFEClientRequester.MessageReceived += XFEClientRequester_MessageReceived;
59 TableRequester.RequestAddress = s_xFEClientRequester.RequestAddress;
60 }
57 61
58 62 private static void XFEClientRequester_MessageReceived(object? sender, ServerInteractiveEventArgs e)
59 63 {
Modified XFEExtension.NetCore.ServerInteractive/Utilities/DataTable/XFEDataDictionaryTable.cs +10 -5
@@ -126,7 +126,7 @@ public class XFEDataDictionaryTable<TValue> : IXFEDataTable where TValue : IIdMo
126 126 {
127 127 case "get":
128 128 Console.Write($"获取{TableShowName}列表请求");
129 UserHelper.ValidatePermission(requestJsonNode["session"], requestJsonNode["deviceInfo"], r.Args.ClientIP, GetPermissionLevel, GetEncryptedUserLoginModelFunction(), GetUsersFunction(), r);
129 UserHelper.ValidatePermission(requestJsonNode["session"], requestJsonNode["deviceInfo"], r.ClientIP, GetPermissionLevel, GetEncryptedUserLoginModelFunction(), GetUsersFunction(), r);
130 130 List<TValue> valueList = [.. GetTableFunction().Values];
131 131 var pageCount = requestJsonNode["pageCount"]?.GetValue<int>() ?? -1;
132 132 if (pageCount == -1)
@@ -158,7 +158,7 @@ public class XFEDataDictionaryTable<TValue> : IXFEDataTable where TValue : IIdMo
158 158 throw new StopAction(() => { }, $"\n无法使用Json转换目标{TableShowName}信息");
159 159 }
160 160 Console.Write($":{item.Id}");
161 UserHelper.ValidatePermission(requestJsonNode["session"], requestJsonNode["deviceInfo"], r.Args.ClientIP, AddPermissionLevel, GetEncryptedUserLoginModelFunction(), GetUsersFunction(), r);
161 UserHelper.ValidatePermission(requestJsonNode["session"], requestJsonNode["deviceInfo"], r.ClientIP, AddPermissionLevel, GetEncryptedUserLoginModelFunction(), GetUsersFunction(), r);
162 162 if (item.Id.IsNullOrWhiteSpace())
163 163 item.Id = Guid.NewGuid().ToString();
164 164 var addTable = GetTableFunction();
@@ -171,7 +171,7 @@ public class XFEDataDictionaryTable<TValue> : IXFEDataTable where TValue : IIdMo
171 171 Console.Write($"删除{TableShowName}请求");
172 172 var id = requestJsonNode["id"]?.ToString();
173 173 Console.Write($":{id}");
174 UserHelper.ValidatePermission(requestJsonNode["session"], requestJsonNode["deviceInfo"], r.Args.ClientIP, RemovePermissionLevel, GetEncryptedUserLoginModelFunction(), GetUsersFunction(), r);
174 UserHelper.ValidatePermission(requestJsonNode["session"], requestJsonNode["deviceInfo"], r.ClientIP, RemovePermissionLevel, GetEncryptedUserLoginModelFunction(), GetUsersFunction(), r);
175 175 if (id.IsNullOrWhiteSpace())
176 176 {
177 177 statusCode = HttpStatusCode.BadRequest;
@@ -194,7 +194,7 @@ public class XFEDataDictionaryTable<TValue> : IXFEDataTable where TValue : IIdMo
194 194 statusCode = HttpStatusCode.BadRequest;
195 195 throw new StopAction(() => { }, $"\n{TableShowName}ID不能为空");
196 196 }
197 UserHelper.ValidatePermission(requestJsonNode["session"], requestJsonNode["deviceInfo"], r.Args.ClientIP, ChangePermissionLevel, GetEncryptedUserLoginModelFunction(), GetUsersFunction(), r);
197 UserHelper.ValidatePermission(requestJsonNode["session"], requestJsonNode["deviceInfo"], r.ClientIP, ChangePermissionLevel, GetEncryptedUserLoginModelFunction(), GetUsersFunction(), r);
198 198 Change(item);
199 199 r.Args.Close();
200 200 break;
@@ -204,9 +204,14 @@ public class XFEDataDictionaryTable<TValue> : IXFEDataTable where TValue : IIdMo
204 204 break;
205 205 }
206 206 }
207 catch (ServerCoreReturnArgs returnArgs)
208 {
209 Console.WriteLine($"[WARN]({r.ServerCore.ServerCoreName}){returnArgs.ReturnMessage}");
210 await returnArgs.Args.ReplyAndClose(returnArgs.ReturnMessage, returnArgs.StatusCode);
211 }
207 212 catch (Exception ex)
208 213 {
209 Console.WriteLine($"[WARN]({r.ServerCore.ServerCoreName}){ex}");
214 Console.WriteLine($"[WARN]({r.ServerCore.ServerCoreName}){ExceptionHelper.GetExceptionMessage(ex)}");
210 215 Console.WriteLine($"[TRACE]{ex.StackTrace}");
211 216 await r.Args.ReplyAndClose(ex.Message, statusCode);
212 217 }
Modified XFEExtension.NetCore.ServerInteractive/Utilities/DataTable/XFEDataListTable.cs +10 -5
@@ -133,7 +133,7 @@ public class XFEDataListTable<T> : IXFEDataTable where T : IIdModel
133 133 {
134 134 case "get":
135 135 Console.Write($"获取{TableShowName}列表请求");
136 UserHelper.ValidatePermission(requestJsonNode["session"], requestJsonNode["deviceInfo"], r.Args.ClientIP, GetPermissionLevel, GetEncryptedUserLoginModelFunction(), GetUsersFunction(), r);
136 UserHelper.ValidatePermission(requestJsonNode["session"], requestJsonNode["deviceInfo"], r.ClientIP, GetPermissionLevel, GetEncryptedUserLoginModelFunction(), GetUsersFunction(), r);
137 137 List<T> tableList = [.. GetTableFunction()];
138 138 var pageCount = requestJsonNode["pageCount"]?.GetValue<int>() ?? -1;
139 139 if (pageCount == -1)
@@ -165,7 +165,7 @@ public class XFEDataListTable<T> : IXFEDataTable where T : IIdModel
165 165 throw new StopAction(() => { }, $"\n无法使用Json转换目标{TableShowName}信息");
166 166 }
167 167 Console.Write($":{item.Id}");
168 UserHelper.ValidatePermission(requestJsonNode["session"], requestJsonNode["deviceInfo"], r.Args.ClientIP, AddPermissionLevel, GetEncryptedUserLoginModelFunction(), GetUsersFunction(), r);
168 UserHelper.ValidatePermission(requestJsonNode["session"], requestJsonNode["deviceInfo"], r.ClientIP, AddPermissionLevel, GetEncryptedUserLoginModelFunction(), GetUsersFunction(), r);
169 169 if (item.Id.IsNullOrWhiteSpace())
170 170 {
171 171 statusCode = HttpStatusCode.BadRequest;
@@ -180,7 +180,7 @@ public class XFEDataListTable<T> : IXFEDataTable where T : IIdModel
180 180 Console.Write($"删除{TableShowName}请求");
181 181 var id = requestJsonNode["id"]?.ToString();
182 182 Console.Write($":{id}");
183 UserHelper.ValidatePermission(requestJsonNode["session"], requestJsonNode["deviceInfo"], r.Args.ClientIP, RemovePermissionLevel, GetEncryptedUserLoginModelFunction(), GetUsersFunction(), r);
183 UserHelper.ValidatePermission(requestJsonNode["session"], requestJsonNode["deviceInfo"], r.ClientIP, RemovePermissionLevel, GetEncryptedUserLoginModelFunction(), GetUsersFunction(), r);
184 184 if (id.IsNullOrWhiteSpace())
185 185 {
186 186 statusCode = HttpStatusCode.BadRequest;
@@ -203,7 +203,7 @@ public class XFEDataListTable<T> : IXFEDataTable where T : IIdModel
203 203 statusCode = HttpStatusCode.BadRequest;
204 204 throw new StopAction(() => { }, $"\n{TableShowName}ID不能为空");
205 205 }
206 UserHelper.ValidatePermission(requestJsonNode["session"], requestJsonNode["deviceInfo"], r.Args.ClientIP, ChangePermissionLevel, GetEncryptedUserLoginModelFunction(), GetUsersFunction(), r);
206 UserHelper.ValidatePermission(requestJsonNode["session"], requestJsonNode["deviceInfo"], r.ClientIP, ChangePermissionLevel, GetEncryptedUserLoginModelFunction(), GetUsersFunction(), r);
207 207 Change(item);
208 208 r.Args.Close();
209 209 break;
@@ -213,9 +213,14 @@ public class XFEDataListTable<T> : IXFEDataTable where T : IIdModel
213 213 break;
214 214 }
215 215 }
216 catch (ServerCoreReturnArgs returnArgs)
217 {
218 Console.WriteLine($"[WARN]({r.ServerCore.ServerCoreName}){returnArgs.ReturnMessage}");
219 await returnArgs.Args.ReplyAndClose(returnArgs.ReturnMessage, returnArgs.StatusCode);
220 }
216 221 catch (Exception ex)
217 222 {
218 Console.WriteLine($"[WARN]({r.ServerCore.ServerCoreName}){ex}");
223 Console.WriteLine($"[WARN]({r.ServerCore.ServerCoreName}){ExceptionHelper.GetExceptionMessage(ex)}");
219 224 Console.WriteLine($"[TRACE]{ex.StackTrace}");
220 225 await r.Args.ReplyAndClose(ex.Message, statusCode);
221 226 }
Modified XFEExtension.NetCore.ServerInteractive/Utilities/DataTable/XFEDataTableManager.cs +1 -1
@@ -36,7 +36,7 @@ public abstract class XFEDataTableManager
36 36 }
37 37 else
38 38 {
39 Console.WriteLine($"[ERROR]({r.ServerCore.ServerCoreName})【{r.Args.ClientIP}】试图查询不存在的表格:{split[1]}");
39 Console.WriteLine($"[ERROR]({r.ServerCore.ServerCoreName})【{r.ClientIP}】试图查询不存在的表格:{split[1]}");
40 40 await r.Args.ReplyAndClose($"试图查询不存在的表格:{execute}", HttpStatusCode.BadRequest);
41 41 }
42 42 }
Modified XFEExtension.NetCore.ServerInteractive/Utilities/Helpers/UserHelper.cs +53 -7
@@ -37,21 +37,70 @@ public static class UserHelper
37 37 user = null;
38 38 session = Regex.Unescape(session);
39 39 var split = session.Split('|');
40 if (encryptedUserLoginModels.FirstOrDefault(user => user.UserLoginModel.Uid == split[0]) is not { } encryptedUserLoginModel || encryptedUserLoginModel.UserLoginModel.DeviceInfo != deviceInfo)
40 if (split.Length != 2 || split[0].IsNullOrWhiteSpace() || split[1].IsNullOrWhiteSpace())
41 {
42 Console.Write($" Session格式无效:length={split.Length}, sessionLength={session.Length}");
43 return UserOperateResult.LoginExpired;
44 }
45 if (encryptedUserLoginModels.FirstOrDefault(user => user.UserLoginModel.Uid == split[0]) is not { } encryptedUserLoginModel)
46 {
47 Console.Write($" Session未找到或已被清理:uid={split[0]}");
41 48 return UserOperateResult.LoginExpired;
42 if (Decrypt<UserLoginModel>(encryptedUserLoginModel.Key, split[1]) is not { } targetUserLoginModel || encryptedUserLoginModel.UserLoginModel.Uid != targetUserLoginModel.Uid)
49 }
50 if (encryptedUserLoginModel.UserLoginModel.DeviceInfo != deviceInfo)
51 {
52 Console.Write($" 设备信息不匹配:uid={split[0]}, expected={FormatForLog(encryptedUserLoginModel.UserLoginModel.DeviceInfo)}, actual={FormatForLog(deviceInfo)}");
53 return UserOperateResult.LoginExpired;
54 }
55 UserLoginModel targetUserLoginModel;
56 try
57 {
58 targetUserLoginModel = Decrypt<UserLoginModel>(encryptedUserLoginModel.Key, split[1]);
59 }
60 catch (Exception ex)
61 {
62 Console.Write($" Session解密失败:uid={split[0]}, error={ex.Message}");
63 return UserOperateResult.LoginExpired;
64 }
65 if (encryptedUserLoginModel.UserLoginModel.Uid != targetUserLoginModel.Uid)
66 {
67 Console.Write($" Session解密失败或用户ID不匹配:uid={split[0]}");
43 68 return UserOperateResult.UserNotFound;
44 if (encryptedUserLoginModel.UserLoginModel.EndDateTime < DateTime.Now || (encryptedUserLoginModel.UserLoginModel.LastIPAddress != ipAddress && !(encryptedUserLoginModel.UserLoginModel.LastIPAddress is "127.0.0.1" or "::1" && ipAddress is "127.0.0.1" or "::1")))
69 }
70 if (encryptedUserLoginModel.UserLoginModel.EndDateTime < DateTime.Now)
71 {
72 Console.Write($" Session到期:uid={split[0]}, expire={encryptedUserLoginModel.UserLoginModel.EndDateTime:O}, now={DateTime.Now:O}");
73 return UserOperateResult.LoginExpired;
74 }
75 if (!IsSameIPAddress(encryptedUserLoginModel.UserLoginModel.LastIPAddress, ipAddress))
76 {
77 Console.Write($" IP地址不匹配:uid={split[0]}, expected={encryptedUserLoginModel.UserLoginModel.LastIPAddress}, actual={ipAddress}, expire={encryptedUserLoginModel.UserLoginModel.EndDateTime:O}");
45 78 return UserOperateResult.LoginExpired;
79 }
46 80 if (GetUser(targetUserLoginModel.Uid, userInfoList) is not IUserInfo userInfo)
81 {
82 Console.Write($" 用户ID未注册:uid={targetUserLoginModel.Uid}");
47 83 return UserOperateResult.UserNotFound;
84 }
48 85 if (!userInfo.Enable)
86 {
87 Console.Write($" 用户已禁用:uid={targetUserLoginModel.Uid}");
49 88 return UserOperateResult.UserDisabled;
89 }
50 90 user = userInfo;
51 91 Console.Write($"({user.UserName})");
52 92 return UserOperateResult.Success;
53 93 }
54 94
95 internal static bool IsSameIPAddress(string loginIPAddress, string requestIPAddress) => loginIPAddress == requestIPAddress || (loginIPAddress is "127.0.0.1" or "::1" && requestIPAddress is "127.0.0.1" or "::1");
96
97 private static string FormatForLog(string value)
98 {
99 if (value.IsNullOrEmpty())
100 return "<empty>";
101 return value.Length <= 16 ? value : $"{value[..16]}...";
102 }
103
55 104 /// <summary>
56 105 /// 获取用户
57 106 /// </summary>
@@ -212,10 +261,7 @@ public static class UserHelper
212 261 {
213 262 var result = ValidateUserPermission(sessionId, deviceInfo, ipAddress, requiredPermissionLevel, encryptedUserLoginModels, userInfoList);
214 263 if (result != UserOperateResult.Success)
215 {
216 Console.Write(OutPutResult(result));
217 264 throw r.Error(OutPutResult(result), HttpStatusCode.Forbidden);
218 }
219 265 }
220 266
221 267 /// <summary>
@@ -276,4 +322,4 @@ public static class UserHelper
276 322 /// <param name="encryptedModel"></param>
277 323 /// <returns></returns>
278 324 public static T Decrypt<T>(string key, string encryptedModel) where T : class, new() => JsonSerializer.Deserialize<T>(AesHelper.Decrypt(encryptedModel, key)) ?? new();
279 }
325 }
Modified XFEExtension.NetCore.ServerInteractive/Utilities/Requester/ClientRequester.cs +27 -2
@@ -22,16 +22,41 @@ public abstract class ClientRequester : IRequesterBase
22 22 internal Dictionary<string, Func<IStandardRequestService>> StandardRequestServiceDictionary = [];
23 23 internal List<(string Pattern, Func<IStandardRequestService> Factory)> WildcardStandardRequestServiceList = [];
24 24 internal Dictionary<string, StandardClientInstanceRequest> StandardClientInstanceRequestDictionary = [];
25 private string _session = string.Empty;
26 private TableRequester? _tableRequester;
25 27 /// <inheritdoc/>
26 28 public string RequestAddress { get; set; } = string.Empty;
27 29 /// <inheritdoc/>
28 public string Session { get; set; } = string.Empty;
30 public string Session
31 {
32 get => _session;
33 set
34 {
35 _session = value;
36 if (TableRequester is not null)
37 TableRequester.Session = value;
38 }
39 }
29 40 /// <inheritdoc/>
30 41 public string DeviceInfo { get; set; } = string.Empty;
31 42 /// <summary>
32 43 /// 表格请求器(如需使用表格相关功能,请通过构建器添加WithTableRequester实例并赋值此属性)
33 44 /// </summary>
34 public TableRequester? TableRequester { get; set; }
45 public TableRequester? TableRequester
46 {
47 get => _tableRequester;
48 set
49 {
50 _tableRequester = value;
51 if (_tableRequester is null) return;
52 if (_tableRequester.RequestAddress.Length == 0)
53 _tableRequester.RequestAddress = RequestAddress;
54 if (_tableRequester.DeviceInfo.Length == 0)
55 _tableRequester.DeviceInfo = DeviceInfo;
56 if (_tableRequester.Session.Length == 0)
57 _tableRequester.Session = Session;
58 }
59 }
35 60 /// <inheritdoc/>
36 61 public event XFEEventHandler<object?, ServerInteractiveEventArgs>? MessageReceived;
37 62
Modified XFEExtension.NetCore.ServerInteractive/Utilities/Server/Services/CoreService/CoreLogService.cs +2 -2
@@ -24,7 +24,7 @@ public partial class CoreLogService : ServerCoreUserServiceBase
24 24 public async Task GetLog()
25 25 {
26 26 Console.Write("获取服务器日志请求");
27 UserHelper.ValidatePermission(Json?["session"], Json?["deviceInfo"], ReturnArgs.Args.ClientIP, GetPermission, GetEncryptedUserLoginModelFunction(), GetUserFunction(), ReturnArgs);
27 UserHelper.ValidatePermission(Json?["session"], Json?["deviceInfo"], ReturnArgs.ClientIP, GetPermission, GetEncryptedUserLoginModelFunction(), GetUserFunction(), ReturnArgs);
28 28 if (!DateTime.TryParse(Json?["startDateTime"], out var startDatetime)) throw Error("起始日期格式不正确");
29 29 if (!DateTime.TryParse(Json?["endDateTime"], out var endDatetime)) throw Error("结束日期格式不正确");
30 30 await Close(XFEConsole.XFEConsole.Log.Export(startDatetime, endDatetime));
@@ -37,7 +37,7 @@ public partial class CoreLogService : ServerCoreUserServiceBase
37 37 public void ClearLog()
38 38 {
39 39 Console.Write("清除服务器日志请求");
40 UserHelper.ValidatePermission(Json?["session"], Json?["deviceInfo"], ReturnArgs.Args.ClientIP, ClearPermission, GetEncryptedUserLoginModelFunction(), GetUserFunction(), ReturnArgs);
40 UserHelper.ValidatePermission(Json?["session"], Json?["deviceInfo"], ReturnArgs.ClientIP, ClearPermission, GetEncryptedUserLoginModelFunction(), GetUserFunction(), ReturnArgs);
41 41 if (File.Exists("server.log"))
42 42 File.Delete("server.log");
43 43 XFEConsole.XFEConsole.Log.Clear();
Modified XFEExtension.NetCore.ServerInteractive/Utilities/Server/Services/CoreService/IpBannerService.cs +3 -3
@@ -30,7 +30,7 @@ public partial class IPBannerService : ServerCoreUserServiceBase
30 30 public async Task GetBannedIPList()
31 31 {
32 32 Console.Write("获取禁止的IP地址列表请求");
33 UserHelper.ValidatePermission(Json?["session"]?.ToString(), Json?["deviceInfo"]?.ToString(), ReturnArgs.Args.ClientIP, GetPermission, GetEncryptedUserLoginModelFunction(), GetUserFunction(), ReturnArgs);
33 UserHelper.ValidatePermission(Json?["session"]?.ToString(), Json?["deviceInfo"]?.ToString(), ReturnArgs.ClientIP, GetPermission, GetEncryptedUserLoginModelFunction(), GetUserFunction(), ReturnArgs);
34 34 await Close(ServerBaseProfile.BannedIPAddressList.ToJson());
35 35 }
36 36
@@ -41,7 +41,7 @@ public partial class IPBannerService : ServerCoreUserServiceBase
41 41 public void AddBannedIP()
42 42 {
43 43 Console.Write($"添加禁止的IP地址请求 添加:{Json?["bannedIP"]}");
44 UserHelper.ValidatePermission(Json?["session"]?.ToString(), Json?["deviceInfo"]?.ToString(), ReturnArgs.Args.ClientIP, AddPermission, GetEncryptedUserLoginModelFunction(), GetUserFunction(), ReturnArgs);
44 UserHelper.ValidatePermission(Json?["session"]?.ToString(), Json?["deviceInfo"]?.ToString(), ReturnArgs.ClientIP, AddPermission, GetEncryptedUserLoginModelFunction(), GetUserFunction(), ReturnArgs);
45 45 if (Json?["bannedIP"] is null) throw Error("无IP地址传入");
46 46 ServerBaseProfile.BannedIPAddressList.Add(new()
47 47 {
@@ -58,7 +58,7 @@ public partial class IPBannerService : ServerCoreUserServiceBase
58 58 public async Task RemoveBannedIP()
59 59 {
60 60 Console.Write($"删除禁止的IP地址请求 移除:{Json?["bannedIP"]}");
61 UserHelper.ValidatePermission(Json?["session"]?.ToString(), Json?["deviceInfo"]?.ToString(), ReturnArgs.Args.ClientIP, RemovePermission, GetEncryptedUserLoginModelFunction(), GetUserFunction(), ReturnArgs);
61 UserHelper.ValidatePermission(Json?["session"]?.ToString(), Json?["deviceInfo"]?.ToString(), ReturnArgs.ClientIP, RemovePermission, GetEncryptedUserLoginModelFunction(), GetUserFunction(), ReturnArgs);
62 62 var targetIP = ServerBaseProfile.BannedIPAddressList.FirstOrDefault(ip => ip.IPAddress == Json?["bannedIP"]?.ToString()) ?? throw Error("无IP地址传入");
63 63 await Close(ServerBaseProfile.BannedIPAddressList.Remove(targetIP).ToString());
64 64 }
Modified XFEExtension.NetCore.ServerInteractive/Utilities/Server/Services/CoreService/UserLoginService.cs +2 -2
@@ -46,7 +46,7 @@ public partial class UserLoginService<T> : ServerCoreUserLoginServiceBase<T> whe
46 46 {
47 47 Uid = user.Id,
48 48 DeviceInfo = deviceInfo,
49 LastIPAddress = ReturnArgs.Args.ClientIP,
49 LastIPAddress = ReturnArgs.ClientIP,
50 50 EndDateTime = DateTime.Now.AddDays(GetLoginKeepDays())
51 51 }
52 52 };
@@ -56,7 +56,7 @@ public partial class UserLoginService<T> : ServerCoreUserLoginServiceBase<T> whe
56 56 else
57 57 {
58 58 userLogin.UserLoginModel.DeviceInfo = deviceInfo;
59 userLogin.UserLoginModel.LastIPAddress = ReturnArgs.Args.ClientIP;
59 userLogin.UserLoginModel.LastIPAddress = ReturnArgs.ClientIP;
60 60 userLogin.UserLoginModel.EndDateTime = DateTime.Now.AddDays(GetLoginKeepDays());
61 61 Console.Write($"到期时间:{userLogin.UserLoginModel.EndDateTime}");
62 62 }
Modified XFEExtension.NetCore.ServerInteractive/Utilities/Server/Services/CoreService/UserReloginService.cs +17 -3
@@ -21,18 +21,32 @@ public partial class UserReloginService<T> : ServerCoreUserLoginServiceBase<T> w
21 21 {
22 22 Console.Write("校验登录请求:");
23 23 var session = Regex.Unescape(Json?["session"]?.ToString() ?? string.Empty);
24 Console.Write(session[..10]);
24 Console.Write(session.Length <= 10 ? session : session[..10]);
25 25 var deviceInfo = Json?["deviceInfo"]?.ToString();
26 26 if (session.IsNullOrWhiteSpace()) throw Error("Session值不能为空");
27 27 if (deviceInfo.IsNullOrWhiteSpace()) throw Error("电脑信息不能为空");
28 28 var split = session.Split('|');
29 if (split.Length != 2 || split[0].IsNullOrWhiteSpace() || split[1].IsNullOrWhiteSpace()) throw Error("Session格式不正确", HttpStatusCode.Forbidden);
29 30 if (GetEncryptedUserLoginModelFunction().FirstOrDefault(user => user.UserLoginModel.Uid == split[0]) is not { } encryptedUserLoginModel) throw Error("Session值不正确或已过期", HttpStatusCode.Forbidden);
30 31 if (encryptedUserLoginModel.UserLoginModel.DeviceInfo != deviceInfo) throw Error("电脑信息不匹配");
31 var userLoginModel = UserHelper.Decrypt<UserLoginModel>(encryptedUserLoginModel.Key, split[1]);
32 UserLoginModel userLoginModel;
33 try
34 {
35 userLoginModel = UserHelper.Decrypt<UserLoginModel>(encryptedUserLoginModel.Key, split[1]);
36 }
37 catch (Exception ex)
38 {
39 Console.WriteLine($"[AUTH] 重登Session解密失败:uid={split[0]}, error={ex.Message}");
40 throw Error("Session值不正确或已过期", HttpStatusCode.Forbidden);
41 }
32 42 if (userLoginModel.Uid.IsNullOrWhiteSpace() || userLoginModel.Uid != encryptedUserLoginModel.UserLoginModel.Uid)
33 43 throw Error("登录用户ID不匹配");
34 44 var user = UserHelper.GetUser(userLoginModel.Uid, GetUserFunction()) ?? throw Error("用户ID未注册", HttpStatusCode.Forbidden);
35 if (userLoginModel.LastIPAddress != ReturnArgs.Args.ClientIP || userLoginModel.LastIPAddress != encryptedUserLoginModel.UserLoginModel.LastIPAddress) throw Error("IP地址不匹配");
45 if (!UserHelper.IsSameIPAddress(userLoginModel.LastIPAddress, ReturnArgs.ClientIP) || !UserHelper.IsSameIPAddress(userLoginModel.LastIPAddress, encryptedUserLoginModel.UserLoginModel.LastIPAddress))
46 {
47 Console.WriteLine($"[AUTH] 重登IP地址不匹配:uid={split[0]}, session={userLoginModel.LastIPAddress}, stored={encryptedUserLoginModel.UserLoginModel.LastIPAddress}, actual={ReturnArgs.ClientIP}");
48 throw Error("IP地址不匹配");
49 }
36 50 if (userLoginModel.EndDateTime < DateTime.Now || userLoginModel.EndDateTime != encryptedUserLoginModel.UserLoginModel.EndDateTime) throw Error("登录已过期");
37 51 if (userLoginModel.DeviceInfo != encryptedUserLoginModel.UserLoginModel.DeviceInfo) throw Error("电脑信息不匹配");
38 52 await Close(JsonSerializer.Serialize(LoginResultConvertFunction(user), JsonSerializerOptions));
Modified XFEExtension.NetCore.ServerInteractive/XFEExtension.NetCore.ServerInteractive.csproj +9 -8
@@ -5,7 +5,7 @@
5 5 <ImplicitUsings>enable</ImplicitUsings>
6 6 <Nullable>enable</Nullable>
7 7 <GenerateDocumentationFile>True</GenerateDocumentationFile>
8 <Version>3.1.0-preview.1.3</Version>
8 <Version>3.1.0</Version>
9 9 <Title>XFEExtension.NetCore.ServerInteractive</Title>
10 10 <RepositoryUrl>https://github.com/XFEstudio/XFEExtension.NetCore.ServerInteractive</RepositoryUrl>
11 11 <AnalysisLevel>latest</AnalysisLevel>
@@ -20,14 +20,15 @@
20 20 <PackageTags>XFE;Server;服务器;XFEExtension</PackageTags>
21 21 <PackageReleaseNotes>
22 22 ## 调整
23
24 优化日志输出与权限校验逻辑,更新项目版本
25 23
26 - 修改 `XFEDataDictionaryTable.cs` 和 `XFEDataListTable.cs` 中的异常日志输出,直接输出 `ex`,提升信息完整性。
27 - 在 `UserHelper.cs` 的 `ValidatePermission` 方法中,新增权限校验失败时的输出逻辑,并抛出异常。
28 - 更新 `XFEExtension.NetCore.ServerInteractive.csproj`:
29 - 项目版本号从 `3.1.0-preview.1.2` 升级到 `3.1.0-preview.1.3`。
30 - 调整发布说明,优化类型名称与输出显示,增强 DataTable 输出信息。
24 优化权限校验与日志输出逻辑
25
26 - 替换 `ValidatePermission` 方法中 `r.Args.ClientIP` 为 `r.ClientIP`。
27 - 增强 `XFEDataDictionaryTable` 和 `XFEDataListTable` 的异常处理,捕获 `ServerCoreReturnArgs`。
28 - 改进 `UserHelper.GetUser` 方法,增加 `session` 校验和日志输出。
29 - 增加 `IsSameIPAddress` 和 `FormatForLog` 辅助方法。
30 - 调整多个服务类中 `ClientIP` 的获取方式。
31 - 更新项目版本号至 `3.1.0`。
31 32
32 33 ## 新增
33 34