退出远程会话后无法访问外部API的问题排查与解决请求
问题
在Windows Server虚拟机中运行一款C#开发、基于Restsharp的控制台工具,用于访问NVD的API(基础地址:https://services.nvd.nist.gov/rest/json/cves/2.0)。工具已配置为计划任务,设置为无需登录用户即可运行。当前遇到的现象:
- 服务器重启后,API访问正常
- 通过远程会话登录虚拟机时,工具仍可正常访问API
- 退出远程会话后,后续API访问失败,报错信息为*"A task was canceled"*
工具核心代码片段:
try { do { System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12; string url = mainUrl + $"resultsPerPage={resultsPerPage}&startIndex={startIndex}&" + parameter; WebProxy proxy = new WebProxy("x.x.x.x", xxxx); RestClientOptions options = new RestClientOptions() { Proxy = proxy, MaxTimeout = 35000, BaseUrl = new Uri(url), UseDefaultCredentials = false }; var client = new RestClient(options); var request = new RestRequest(); request.AddHeader("api-Key", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); var response = await client.ExecuteAsync(request); if (response.IsSuccessful) { // Read result as string string eventContent = response.Content; // Parse string in JArray parsedResult = JObject.Parse(eventContent); debugString = parsedResult.ToString(); ... if (parsedResult["totalResults"].Value<int>() <= startIndex) { runTask = false; } } else { runTask = false; } await Task.Delay(7000); } else { DebugLogger.Instance.add(response.StatusCode + "(" + response.ErrorMessage + ")"); } } while (runTask == true); return xxxxxxxx; } catch (Exception ex) { DebugLogger.Instance.add(ex.ToString()); throw ex; }
操作步骤:
- 配置计划任务让工具开机自动运行
- 重启服务器
- 服务器重启后,API访问符合预期
- 通过远程会话登录服务器,API访问仍正常
- 退出远程会话后,API访问不再正常
原因分析
这个问题的核心是代理权限依赖用户会话:
- 当用户退出远程会话后,计划任务使用的服务账号无法获取代理所需的网络会话上下文,导致代理连接超时,最终触发Restsharp的任务取消报错("A task was canceled"本质是请求超时或连接失败后的包装错误)。
- 服务器重启后未登录时,系统可能保留了初始的网络会话上下文;而登录再退出后,用户会话销毁,代理的权限验证或网络路径被切断。
- 代码中
UseDefaultCredentials = false,但代理未配置明确的凭据,导致无用户会话时,代理请求无法通过身份验证,最终超时失败。
解决方案
1. 为代理配置明确的凭据
在创建WebProxy时,指定服务账号的凭据,确保无用户会话时也能通过代理验证:
WebProxy proxy = new WebProxy("x.x.x.x", xxxx); // 替换为服务账号的用户名、密码和域 proxy.Credentials = new NetworkCredential("service-username", "service-password", "domain");
2. 调整计划任务的运行选项
- 打开计划任务属性,在常规选项卡中,确保勾选*"不管用户是否登录都要运行",并勾选"使用最高权限运行"*。
- 在设置选项卡中,取消勾选*"如果任务运行时间超过X小时就停止"*,避免任务被强制终止。
3. 优化请求配置
- 修正BaseUrl用法:Restsharp的
BaseUrl应设为API基础地址,而非完整请求URL,参数通过AddQueryParameter添加,避免URL拼接错误:
RestClientOptions options = new RestClientOptions() { Proxy = proxy, MaxTimeout = 60000, // 适当延长超时到60秒,避免代理连接慢导致超时 BaseUrl = new Uri(mainUrl), // 仅设为API基础地址 UseDefaultCredentials = false }; var request = new RestRequest(); request.AddQueryParameter("resultsPerPage", resultsPerPage.ToString()); request.AddQueryParameter("startIndex", startIndex.ToString()); // 其他参数通过AddQueryParameter添加
4. 调整服务器网络会话配置
- 通过组策略调整远程桌面会话设置:
计算机配置 -> 管理模板 -> Windows组件 -> 远程桌面服务 -> 远程桌面会话主机 -> 会话时间限制,设置合适的会话保留时间,避免用户退出时立即销毁网络资源。 - 确认代理服务器允许服务账号的无会话访问,将服务账号加入代理白名单,取消会话存在性验证。
内容的提问来源于stack exchange,提问作者ABF
相关产品推荐
相关产品推荐

