From fab9cc2872d101b9a5db589020f0d86d69437921 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A7=E7=9F=B3=E5=A4=B4?= Date: Sun, 13 Jul 2025 22:08:16 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BA=94=E7=94=A8=E9=80=80=E5=87=BA=E6=97=B6?= =?UTF-8?q?=EF=BC=8C=E9=94=80=E6=AF=81AppClient=E5=AF=B9=E8=B1=A1=E4=B9=8B?= =?UTF-8?q?=E5=90=8E=EF=BC=8C=E4=B8=8D=E5=86=8D=E5=85=81=E8=AE=B8=E8=AF=B7?= =?UTF-8?q?=E6=B1=82=E4=B8=9A=E5=8A=A1=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Samples/TestA/TestA.csproj | 2 +- Samples/TestB/TestB.csproj | 2 +- Stardust.Server/Controllers/AppController.cs | 12 +++++------ Stardust.Server/Controllers/CubeController.cs | 10 +++++----- Stardust.Server/Controllers/NodeController.cs | 20 ++++++++----------- .../Controllers/OAuthController.cs | 2 +- Stardust.Server/Services/NodeService.cs | 12 +++++------ Stardust.Server/Services/RegistryService.cs | 8 ++++---- Stardust.Server/Services/TokenService.cs | 20 +++++++++---------- Stardust.Server/Setting.cs | 2 +- Stardust.Server/Stardust.Server.csproj | 2 +- Stardust.Web/Controllers/ConfigController.cs | 2 +- Stardust.Web/Stardust.Web.csproj | 4 ++-- Stardust/Monitors/StarTracer.cs | 13 ++++++------ Stardust/Stardust.csproj | 4 ++-- Test/Test.csproj | 2 +- 16 files changed, 57 insertions(+), 60 deletions(-) diff --git a/Samples/TestA/TestA.csproj b/Samples/TestA/TestA.csproj index d8fea4ab..c786fbf9 100644 --- a/Samples/TestA/TestA.csproj +++ b/Samples/TestA/TestA.csproj @@ -18,7 +18,7 @@ - + diff --git a/Samples/TestB/TestB.csproj b/Samples/TestB/TestB.csproj index 5ef85438..c30feee6 100644 --- a/Samples/TestB/TestB.csproj +++ b/Samples/TestB/TestB.csproj @@ -18,7 +18,7 @@ - + diff --git a/Stardust.Server/Controllers/AppController.cs b/Stardust.Server/Controllers/AppController.cs index 3aea0dba..4cd09b13 100644 --- a/Stardust.Server/Controllers/AppController.cs +++ b/Stardust.Server/Controllers/AppController.cs @@ -89,7 +89,7 @@ public class AppController : BaseController var clientId = model.ClientId; app ??= _registryService.Register(model.AppId, model.Secret, set.AppAutoRegister, ip, clientId); - _app = app ?? throw new ApiException(12, "应用鉴权失败"); + _app = app ?? throw new ApiException(ApiCode.Unauthorized, "应用鉴权失败"); _registryService.Login(app, model, ip, _setting); @@ -241,7 +241,7 @@ public class AppController : BaseController private async Task HandleNotify(WebSocket socket, App app, String clientId, String ip, CancellationToken cancellationToken) { - if (app == null) throw new ApiException(401, "未登录!"); + if (app == null) throw new ApiException(ApiCode.Unauthorized, "未登录!"); using var session = new AppCommandSession(socket) { @@ -286,10 +286,10 @@ public class AppController : BaseController var target = App.FindByName(code) ?? throw new ArgumentOutOfRangeException(nameof(model.Code), "无效应用"); var app = _app; - if (app == null || app.AllowControlNodes.IsNullOrEmpty()) throw new ApiException(401, "无权操作!"); + if (app == null || app.AllowControlNodes.IsNullOrEmpty()) throw new ApiException(ApiCode.Unauthorized, "无权操作!"); if (app.AllowControlNodes != "*" && !target.Name.EqualIgnoreCase(app.AllowControlNodes.Split(","))) - throw new ApiException(403, $"[{app}]无权操作应用[{target}]!\n安全设计需要,默认禁止所有应用向其它应用发送控制指令。\n可在注册中心应用系统中修改[{app}]的可控节点,添加[{target.Name}],或者设置为*所有应用。"); + throw new ApiException(ApiCode.Forbidden, $"[{app}]无权操作应用[{target}]!\n安全设计需要,默认禁止所有应用向其它应用发送控制指令。\n可在注册中心应用系统中修改[{app}]的可控节点,添加[{target.Name}],或者设置为*所有应用。"); var cmd = await _registryService.SendCommand(target, clientId, model, app + ""); @@ -302,7 +302,7 @@ public class AppController : BaseController [HttpPost(nameof(CommandReply))] public Int32 CommandReply(CommandReplyModel model) { - if (_app == null) throw new ApiException(401, "节点未登录"); + if (_app == null) throw new ApiException(ApiCode.Unauthorized, "节点未登录"); var cmd = _registryService.CommandReply(_app, model); @@ -319,7 +319,7 @@ public class AppController : BaseController info = new Service { Name = serviceName, Enable = true }; info.Insert(); } - if (!info.Enable) throw new ApiException(403, $"服务[{serviceName}]已停用!"); + if (!info.Enable) throw new ApiException(ApiCode.Forbidden, $"服务[{serviceName}]已停用!"); return info; } diff --git a/Stardust.Server/Controllers/CubeController.cs b/Stardust.Server/Controllers/CubeController.cs index d41afa83..eb20f6d5 100644 --- a/Stardust.Server/Controllers/CubeController.cs +++ b/Stardust.Server/Controllers/CubeController.cs @@ -16,14 +16,14 @@ public class CubeController : ControllerBase #region 附件 private async Task<(Attachment att, String filePath)> GetFile(String id) { - if (id.IsNullOrEmpty()) throw new ApiException(404, "非法附件编号"); + if (id.IsNullOrEmpty()) throw new ApiException(ApiCode.NotFound, "非法附件编号"); // 去掉仅用于装饰的后缀名 var p = id.IndexOf('.'); if (p > 0) id = id[..p]; var att = Attachment.FindById(id.ToLong()); - if (att == null) throw new ApiException(404, "找不到附件信息"); + if (att == null) throw new ApiException(ApiCode.NotFound, "找不到附件信息"); var set = StarServerSetting.Current; @@ -32,14 +32,14 @@ public class CubeController : ControllerBase if (filePath.IsNullOrEmpty() || !System.IO.File.Exists(filePath)) { var url = att.Source; - if (url.IsNullOrEmpty()) throw new ApiException(404, "找不到附件文件"); + if (url.IsNullOrEmpty()) throw new ApiException(ApiCode.NotFound, "找不到附件文件"); var rs = await att.Fetch(url, set.UploadPath); - if (!rs) throw new ApiException(404, "附件远程抓取失败"); + if (!rs) throw new ApiException(ApiCode.NotFound, "附件远程抓取失败"); filePath = att.GetFilePath(set.UploadPath); } - if (filePath.IsNullOrEmpty() || !System.IO.File.Exists(filePath)) throw new ApiException(404, "附件文件不存在"); + if (filePath.IsNullOrEmpty() || !System.IO.File.Exists(filePath)) throw new ApiException(ApiCode.NotFound, "附件文件不存在"); return (att, filePath); } diff --git a/Stardust.Server/Controllers/NodeController.cs b/Stardust.Server/Controllers/NodeController.cs index 2c29577f..30c608eb 100644 --- a/Stardust.Server/Controllers/NodeController.cs +++ b/Stardust.Server/Controllers/NodeController.cs @@ -26,23 +26,19 @@ public class NodeController : BaseController { private Node _node; private String _clientId; - private readonly ICacheProvider _cacheProvider; private readonly ITracer _tracer; private readonly IOptions _jsonOptions; private readonly NodeService _nodeService; private readonly TokenService _tokenService; - private readonly DeployService _deployService; private readonly NodeSessionManager _sessionManager; private readonly StarServerSetting _setting; - public NodeController(NodeService nodeService, TokenService tokenService, DeployService deployService, NodeSessionManager sessionManager, StarServerSetting setting, ICacheProvider cacheProvider, IServiceProvider serviceProvider, ITracer tracer, IOptions jsonOptions) : base(serviceProvider) + public NodeController(NodeService nodeService, TokenService tokenService, NodeSessionManager sessionManager, StarServerSetting setting, IServiceProvider serviceProvider, ITracer tracer, IOptions jsonOptions) : base(serviceProvider) { - _cacheProvider = cacheProvider; _tracer = tracer; - this._jsonOptions = jsonOptions; + _jsonOptions = jsonOptions; _nodeService = nodeService; _tokenService = tokenService; - _deployService = deployService; _sessionManager = sessionManager; _setting = setting; } @@ -90,7 +86,7 @@ public class NodeController : BaseController var oldSecret = node?.Secret; _node = node; - if (node != null && !node.Enable) throw new ApiException(99, "禁止登录"); + if (node != null && !node.Enable) throw new ApiException(ApiCode.Unauthorized, "禁止登录"); // 支持自动识别2020年的XCoder版本,兼容性处理 if (inf.ProductCode.IsNullOrEmpty()) @@ -113,7 +109,7 @@ public class NodeController : BaseController node ??= _nodeService.Register(inf, ip, _setting); - if (node == null) throw new ApiException(12, "节点鉴权失败"); + if (node == null) throw new ApiException(ApiCode.Unauthorized, "节点鉴权失败"); var tokenModel = _nodeService.Login(node, inf, ip, _setting); @@ -207,7 +203,7 @@ public class NodeController : BaseController [HttpGet(nameof(Upgrade))] public UpgradeInfo Upgrade(String channel) { - var node = _node ?? throw new ApiException(401, "节点未登录"); + var node = _node ?? throw new ApiException(ApiCode.Unauthorized, "节点未登录"); // 基础路径 var uri = Request.GetRawUrl().ToString(); @@ -291,7 +287,7 @@ public class NodeController : BaseController [HttpPost(nameof(Report))] public async Task Report(Int32 id) { - var node = _node ?? throw new ApiException(401, "节点未登录"); + var node = _node ?? throw new ApiException(ApiCode.Unauthorized, "节点未登录"); var cmd = NodeCommand.FindById(id); if (cmd != null && cmd.NodeID == node.ID) @@ -335,7 +331,7 @@ public class NodeController : BaseController /// 服务 /// [HttpPost(nameof(CommandReply))] - public Int32 CommandReply(CommandReplyModel model) => _node == null ? throw new ApiException(401, "节点未登录") : _nodeService.CommandReply(_node, model, Token); + public Int32 CommandReply(CommandReplyModel model) => _node == null ? throw new ApiException(ApiCode.Unauthorized, "节点未登录") : _nodeService.CommandReply(_node, model, Token); #endregion #region 下行通知 @@ -370,7 +366,7 @@ public class NodeController : BaseController private async Task HandleNotify(WebSocket socket, String token, String ip, CancellationToken cancellationToken) { var (_, node, error) = _nodeService.DecodeToken(token, _setting.TokenSecret); - _node = node ?? throw new ApiException(401, $"未登录![ip={ip}]"); + _node = node ?? throw new ApiException(ApiCode.Unauthorized, $"未登录![ip={ip}]"); if (error != null) throw error; using var session = new NodeCommandSession(socket) diff --git a/Stardust.Server/Controllers/OAuthController.cs b/Stardust.Server/Controllers/OAuthController.cs index dc4ade16..0a3f5077 100644 --- a/Stardust.Server/Controllers/OAuthController.cs +++ b/Stardust.Server/Controllers/OAuthController.cs @@ -63,7 +63,7 @@ public class OAuthController : ControllerBase var app = App.FindByName(jwt?.Subject); if (app == null || !app.Enable) { - ex ??= new ApiException(403, $"无效应用[{jwt.Subject}]"); + ex ??= new ApiException(ApiCode.Unauthorized, $"无效应用[{jwt.Subject}]"); } if (clientId.IsNullOrEmpty()) clientId = jwt.Id; diff --git a/Stardust.Server/Services/NodeService.cs b/Stardust.Server/Services/NodeService.cs index 18cb154d..13f26efe 100644 --- a/Stardust.Server/Services/NodeService.cs +++ b/Stardust.Server/Services/NodeService.cs @@ -246,11 +246,11 @@ public class NodeService private Node AutoRegister(Node node, LoginInfo inf, String ip, StarServerSetting set) { - if (!set.AutoRegister) throw new ApiException(12, "禁止自动注册"); + if (!set.AutoRegister) throw new ApiException(ApiCode.Forbidden, "禁止自动注册"); // 检查白名单 //var ip = UserHost; - if (!IsMatchWhiteIP(set.WhiteIP, ip)) throw new ApiException(13, "非法来源,禁止注册"); + if (!IsMatchWhiteIP(set.WhiteIP, ip)) throw new ApiException(ApiCode.Forbidden, "非法来源,禁止注册"); using var span = _tracer?.NewSpan(nameof(AutoRegister), new { inf.ProductCode, inf.Node }); @@ -768,10 +768,10 @@ public class NodeService if (node == null) throw new ArgumentOutOfRangeException(nameof(model.Code), "无效节点"); var (_, app) = _tokenService.DecodeToken(token, setting.TokenSecret); - if (app == null || app.AllowControlNodes.IsNullOrEmpty()) throw new ApiException(401, "无权操作!"); + if (app == null || app.AllowControlNodes.IsNullOrEmpty()) throw new ApiException(ApiCode.Unauthorized, "无权操作!"); if (app.AllowControlNodes != "*" && !node.Code.EqualIgnoreCase(app.AllowControlNodes.Split(","))) - throw new ApiException(403, $"[{app}]无权操作节点[{node}]!\n安全设计需要,默认禁止所有应用向任意节点发送控制指令。\n可在注册中心应用系统中修改[{app}]的可控节点,添加[{node.Code}],或者设置为*所有节点。"); + throw new ApiException(ApiCode.Forbidden, $"[{app}]无权操作节点[{node}]!\n安全设计需要,默认禁止所有应用向任意节点发送控制指令。\n可在注册中心应用系统中修改[{app}]的可控节点,添加[{node.Code}],或者设置为*所有节点。"); return await SendCommand(node, model, app + ""); } @@ -863,9 +863,9 @@ public class NodeService if (!rs || node == null) { if (node != null) - ex = new ApiException(403, $"[{node.Name}/{node.Code}]非法访问 {message}"); + ex = new ApiException(ApiCode.Forbidden, $"[{node.Name}/{node.Code}]非法访问 {message}"); else - ex = new ApiException(403, $"[{jwt.Subject}]非法访问 {message}"); + ex = new ApiException(ApiCode.Forbidden, $"[{jwt.Subject}]非法访问 {message}"); } return (jwt, node, ex); diff --git a/Stardust.Server/Services/RegistryService.cs b/Stardust.Server/Services/RegistryService.cs index 7ddd2573..35f3c65d 100644 --- a/Stardust.Server/Services/RegistryService.cs +++ b/Stardust.Server/Services/RegistryService.cs @@ -45,12 +45,12 @@ public class RegistryService // 检查黑白名单 if (!app.MatchIp(ip)) - throw new ApiException(403, $"应用[{app.Name}]禁止{ip}访问!"); + throw new ApiException(ApiCode.Forbidden, $"应用[{app.Name}]禁止{ip}访问!"); if (app.Project != null && !app.Project.MatchIp(ip)) - throw new ApiException(403, $"项目[{app.Project}]禁止{ip}访问!"); + throw new ApiException(ApiCode.Forbidden, $"项目[{app.Project}]禁止{ip}访问!"); // 检查应用有效性 - if (!app.Enable) throw new ApiException(403, $"应用[{app.Name}]已禁用!"); + if (!app.Enable) throw new ApiException(ApiCode.Forbidden, $"应用[{app.Name}]已禁用!"); // 未设置密钥,直接通过 if (app.Secret.IsNullOrEmpty()) return true; @@ -567,7 +567,7 @@ public class RegistryService if (cmd == null) return null; // 防止越权 - if (cmd.AppId != app.Id) throw new ApiException(403, $"[{app}]越权访问[{cmd.AppName}]的服务"); + if (cmd.AppId != app.Id) throw new ApiException(ApiCode.Forbidden, $"[{app}]越权访问[{cmd.AppName}]的服务"); cmd.Status = model.Status; cmd.Result = model.Data; diff --git a/Stardust.Server/Services/TokenService.cs b/Stardust.Server/Services/TokenService.cs index 9f010426..90f4454e 100644 --- a/Stardust.Server/Services/TokenService.cs +++ b/Stardust.Server/Services/TokenService.cs @@ -32,13 +32,13 @@ public class TokenService // 检查黑白名单 if (!app.MatchIp(ip)) - throw new ApiException(403, $"应用[{username}]禁止{ip}访问!"); + throw new ApiException(ApiCode.Forbidden, $"应用[{username}]禁止{ip}访问!"); if (app.Project != null && !app.Project.MatchIp(ip)) - throw new ApiException(403, $"项目[{app.Project}]禁止{ip}访问!"); + throw new ApiException(ApiCode.Forbidden, $"项目[{app.Project}]禁止{ip}访问!"); // 检查应用有效性 - if (!app.Enable) throw new ApiException(403, $"应用[{username}]已禁用!"); - if (!app.Secret.IsNullOrEmpty() && password != app.Secret) throw new ApiException(401, $"非法访问应用[{username}]!"); + if (!app.Enable) throw new ApiException(ApiCode.Forbidden, $"应用[{username}]已禁用!"); + if (!app.Secret.IsNullOrEmpty() && password != app.Secret) throw new ApiException(ApiCode.Forbidden, $"非法访问应用[{username}]!"); return app; } @@ -113,7 +113,7 @@ public class TokenService }; Exception ex = null; - if (!jwt.TryDecode(token, out var message)) ex = new ApiException(403, $"[{jwt.Subject}]非法访问 {message}"); + if (!jwt.TryDecode(token, out var message)) ex = new ApiException(ApiCode.Forbidden, $"[{jwt.Subject}]非法访问 {message}"); return (jwt, ex); } @@ -133,7 +133,7 @@ public class TokenService Algorithm = ss[0], Secret = ss[1], }; - if (!jwt.TryDecode(token, out var message)) throw new ApiException(403, $"非法访问[{jwt.Subject}],{message}"); + if (!jwt.TryDecode(token, out var message)) throw new ApiException(ApiCode.Forbidden, $"非法访问[{jwt.Subject}],{message}"); // 验证应用 var app = App.FindByName(jwt.Subject); @@ -141,11 +141,11 @@ public class TokenService { // 可能是StarAgent混用了token var node = Data.Nodes.Node.FindByCode(jwt.Subject); - if (node == null) throw new ApiException(403, $"无效应用[{jwt.Subject}]"); + if (node == null) throw new ApiException(ApiCode.Forbidden, $"无效应用[{jwt.Subject}]"); app = new App { Name = node.Code, DisplayName = node.Name, Enable = true }; } - if (!app.Enable) throw new ApiException(403, $"已停用应用[{jwt.Subject}]"); + if (!app.Enable) throw new ApiException(ApiCode.Forbidden, $"已停用应用[{jwt.Subject}]"); return (jwt, app); } @@ -167,11 +167,11 @@ public class TokenService }; Exception ex = null; - if (!jwt.TryDecode(token, out var message)) ex = new ApiException(403, $"非法访问 {message}"); + if (!jwt.TryDecode(token, out var message)) ex = new ApiException(ApiCode.Forbidden, $"非法访问 {message}"); // 验证应用 var app = App.FindByName(jwt.Subject); - if ((app == null || !app.Enable) && ex == null) ex = new ApiException(401, $"无效应用[{jwt.Subject}]"); + if ((app == null || !app.Enable) && ex == null) ex = new ApiException(ApiCode.NotFound, $"无效应用[{jwt.Subject}]"); return (app, ex); } diff --git a/Stardust.Server/Setting.cs b/Stardust.Server/Setting.cs index 8ebc5ce7..2f778bd3 100644 --- a/Stardust.Server/Setting.cs +++ b/Stardust.Server/Setting.cs @@ -1,7 +1,7 @@ using System.ComponentModel; using NewLife; using NewLife.Configuration; -using NewLife.Remoting.Extensions.Models; +using NewLife.Remoting.Models; using NewLife.Security; using XCode.Configuration; diff --git a/Stardust.Server/Stardust.Server.csproj b/Stardust.Server/Stardust.Server.csproj index 0133030b..4db5b6b1 100644 --- a/Stardust.Server/Stardust.Server.csproj +++ b/Stardust.Server/Stardust.Server.csproj @@ -47,7 +47,7 @@ - + diff --git a/Stardust.Web/Controllers/ConfigController.cs b/Stardust.Web/Controllers/ConfigController.cs index f486b634..0cd3c5ea 100644 --- a/Stardust.Web/Controllers/ConfigController.cs +++ b/Stardust.Web/Controllers/ConfigController.cs @@ -29,7 +29,7 @@ public class ConfigController : ControllerBase public ConfigInfo GetAll(String appId, String secret, String scope, Int32 version) { if (appId.IsNullOrEmpty()) throw new ArgumentNullException(nameof(appId)); - if (ManageProvider.User == null) throw new ApiException(401, "未登录!"); + if (ManageProvider.User == null) throw new ApiException(ApiCode.Unauthorized, "未登录!"); // 验证 var app = Valid(appId, secret, out var online); diff --git a/Stardust.Web/Stardust.Web.csproj b/Stardust.Web/Stardust.Web.csproj index 2f9341bd..d3ed483d 100644 --- a/Stardust.Web/Stardust.Web.csproj +++ b/Stardust.Web/Stardust.Web.csproj @@ -50,10 +50,10 @@ - + - + diff --git a/Stardust/Monitors/StarTracer.cs b/Stardust/Monitors/StarTracer.cs index 7dea6d20..e41072d0 100644 --- a/Stardust/Monitors/StarTracer.cs +++ b/Stardust/Monitors/StarTracer.cs @@ -105,9 +105,10 @@ public class StarTracer : DefaultTracer if (_inited) return; // 自动从本地星尘代理获取地址 - if (Client == null) throw new ArgumentNullException(nameof(Client)); + var client = Client; + if (client == null) throw new ArgumentNullException(nameof(Client)); - var server = Client is ClientBase cbase ? cbase.Server : (Client + ""); + var server = client is ClientBase cbase ? cbase.Server : (client + ""); WriteLog("星尘监控中心 Server={0} AppId={1} ClientId={2}", server, AppId, ClientId); _inited = true; @@ -127,10 +128,10 @@ public class StarTracer : DefaultTracer Init(); var client = Client; - if (client == null) return; + if (client == null || client is IDisposable2 ds && ds.Disposed) return; // 构建应用信息。如果应用心跳已存在,则监控上报时不需要携带应用性能信息 - if (EnableMeter && Client is not ClientBase) + if (EnableMeter && client is not ClientBase) { if (_appInfo == null) _appInfo = new AppInfo(_process) { Version = _version }; @@ -202,7 +203,7 @@ public class StarTracer : DefaultTracer } catch (Exception ex) { - var source = (Client as ApiHttpClient)?.Source; + var source = (client as ApiHttpClient)?.Source; var ex2 = ex is AggregateException aex ? aex.InnerException : ex; if (ex2 is TaskCanceledException tce) Log?.Debug("监控中心[{0}]出错 {1} TaskId={2}", source, ex2.GetType().Name, tce.Task?.Id); @@ -246,7 +247,7 @@ public class StarTracer : DefaultTracer void ProcessFails() { var client = Client; - if (client == null) return; + if (client == null || client is IDisposable2 ds && ds.Disposed) return; while (_fails.TryDequeue(out var model)) { diff --git a/Stardust/Stardust.csproj b/Stardust/Stardust.csproj index 76fe9a5f..b34d0b08 100644 --- a/Stardust/Stardust.csproj +++ b/Stardust/Stardust.csproj @@ -119,10 +119,10 @@ - + - + diff --git a/Test/Test.csproj b/Test/Test.csproj index 6a2483cf..52043eec 100644 --- a/Test/Test.csproj +++ b/Test/Test.csproj @@ -33,7 +33,7 @@ - +