From f7091e6fd5c8543c339794d485f02d548b31411e Mon Sep 17 00:00:00 2001 From: "Gui.H" Date: Fri, 1 Jul 2022 11:45:27 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4api=E4=B8=BAhostingstarup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/SystemController.cs | 151 ++++++++---------- FastTunnel.Api/FastTunnel.Api.csproj | 33 ++-- FastTunnel.Api/FastTunnelApiHostingStartup.cs | 80 ++++++++++ FastTunnel.Core/FastTunnel.Core.csproj | 4 - .../Handlers/Server/LoginHandler.cs | 14 ++ FastTunnel.Server/Program.cs | 3 + .../Properties/launchSettings.json | 5 +- FastTunnel.Server/Startup.cs | 38 ----- 8 files changed, 186 insertions(+), 142 deletions(-) create mode 100644 FastTunnel.Api/FastTunnelApiHostingStartup.cs diff --git a/FastTunnel.Api/Controllers/SystemController.cs b/FastTunnel.Api/Controllers/SystemController.cs index 5186156..0f6c9f5 100644 --- a/FastTunnel.Api/Controllers/SystemController.cs +++ b/FastTunnel.Api/Controllers/SystemController.cs @@ -13,101 +13,88 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -namespace FastTunnel.Api.Controllers +namespace FastTunnel.Api.Controllers; + +public class SystemController : BaseController { - public class SystemController : BaseController + readonly FastTunnelServer fastTunnelServer; + + public SystemController(FastTunnelServer fastTunnelServer) { - readonly FastTunnelServer fastTunnelServer; + this.fastTunnelServer = fastTunnelServer; + } - public SystemController(FastTunnelServer fastTunnelServer) + /// + /// 获取当前等待响应的请求 + /// + /// + [HttpGet] + public ApiResponse GetResponseTempList() + { + ApiResponse.data = new { - this.fastTunnelServer = fastTunnelServer; - } - - /// - /// 获取当前等待响应的请求数 - /// - /// - [HttpGet] - [Obsolete("使用 GetResponseTempList 替换")] - public ApiResponse GetResponseTempCount() - { - ApiResponse.data = fastTunnelServer.ResponseTasks.Count; - return ApiResponse; - } - - /// - /// 获取当前等待响应的请求 - /// - /// - [HttpGet] - public ApiResponse GetResponseTempList() - { - ApiResponse.data = new + Count = fastTunnelServer.ResponseTasks.Count, + Rows = fastTunnelServer.ResponseTasks.Select(x => new { - Count = fastTunnelServer.ResponseTasks.Count, - Rows = fastTunnelServer.ResponseTasks.Select(x => new - { - x.Key - }) - }; + x.Key + }) + }; - return ApiResponse; - } + return ApiResponse; + } - /// - /// 获取当前映射的所有站点信息 - /// - /// - [HttpGet] - public ApiResponse GetAllWebList() + /// + /// 获取当前映射的所有站点信息 + /// + /// + [HttpGet] + public ApiResponse GetAllWebList() + { + ApiResponse.data = new { - ApiResponse.data = new - { - Count = fastTunnelServer.WebList.Count, - Rows = fastTunnelServer.WebList.Select(x => new { x.Key, x.Value.WebConfig.LocalIp, x.Value.WebConfig.LocalPort }) - }; + Count = fastTunnelServer.WebList.Count, + Rows = fastTunnelServer.WebList.Select(x => new { x.Key, x.Value.WebConfig.LocalIp, x.Value.WebConfig.LocalPort }) + }; - return ApiResponse; - } + return ApiResponse; + } - /// - /// 获取服务端配置信息 - /// - /// - [HttpGet] - public ApiResponse GetServerOption() + /// + /// 获取服务端配置信息 + /// + /// + [HttpGet] + public ApiResponse GetServerOption() + { + ApiResponse.data = fastTunnelServer.ServerOption; + return ApiResponse; + } + + /// + /// 获取所有端口转发映射列表 + /// + /// + [HttpGet] + public ApiResponse GetAllForwardList() + { + ApiResponse.data = new { - ApiResponse.data = fastTunnelServer.ServerOption; - return ApiResponse; - } + Count = fastTunnelServer.ForwardList.Count, + Rows = fastTunnelServer.ForwardList.Select(x => new { x.Key, x.Value.SSHConfig.LocalIp, x.Value.SSHConfig.LocalPort, x.Value.SSHConfig.RemotePort }) - /// - /// 获取所有端口转发映射列表 - /// - /// - [HttpGet] - public ApiResponse GetAllForwardList() - { - ApiResponse.data = new - { - Count = fastTunnelServer.ForwardList.Count, - Rows = fastTunnelServer.ForwardList.Select(x => new { x.Key, x.Value.SSHConfig.LocalIp, x.Value.SSHConfig.LocalPort, x.Value.SSHConfig.RemotePort }) + }; - }; + return ApiResponse; + } - return ApiResponse; - } - - /// - /// 获取当前客户端在线数量 - /// - /// - [HttpGet] - public ApiResponse GetOnlineClientCount() - { - ApiResponse.data = fastTunnelServer.ConnectedClientCount; - return ApiResponse; - } + /// + /// 获取当前客户端在线数量 + /// + /// + [HttpGet] + public ApiResponse GetOnlineClientCount() + { + ApiResponse.data = fastTunnelServer.ConnectedClientCount; + return ApiResponse; } } diff --git a/FastTunnel.Api/FastTunnel.Api.csproj b/FastTunnel.Api/FastTunnel.Api.csproj index 5101981..b59cfa9 100644 --- a/FastTunnel.Api/FastTunnel.Api.csproj +++ b/FastTunnel.Api/FastTunnel.Api.csproj @@ -1,19 +1,20 @@ - - net6.0 - 1.1.0 - https://github.com/FastTunnel/FastTunnel/tree/v2/FastTunnel.Api - https://github.com/FastTunnel/FastTunnel/tree/v2/FastTunnel.Api - - - - - - - - + + net6.0 + 1.1.0 + https://github.com/FastTunnel/FastTunnel/tree/v2/FastTunnel.Api + https://github.com/FastTunnel/FastTunnel/tree/v2/FastTunnel.Api + + + + + + + + + - - - + + + diff --git a/FastTunnel.Api/FastTunnelApiHostingStartup.cs b/FastTunnel.Api/FastTunnelApiHostingStartup.cs new file mode 100644 index 0000000..fbe2663 --- /dev/null +++ b/FastTunnel.Api/FastTunnelApiHostingStartup.cs @@ -0,0 +1,80 @@ +// Licensed under the Apache License, Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// https://github.com/FastTunnel/FastTunnel/edit/v2/LICENSE +// Copyright (c) 2019 Gui.H + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using FastTunnel.Api; +using FastTunnel.Api.Filters; +using FastTunnel.Core.Config; +using FastTunnel.Core.Extensions; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.IdentityModel.Tokens; + +[assembly: HostingStartup(typeof(FastTunnelApiHostingStartup))] + +namespace FastTunnel.Api; + +public class FastTunnelApiHostingStartup : IHostingStartup +{ + public void Configure(IWebHostBuilder builder) + { + Debug.WriteLine("FastTunnelApiHostingStartup Configured"); + + builder.ConfigureServices((webHostBuilderContext, services) => + { + services.AddControllers(); + + var serverOptions = webHostBuilderContext.Configuration.GetSection("FastTunnel").Get(); + if (serverOptions.Api?.JWT != null) + { + services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) + .AddJwtBearer(options => + { + options.TokenValidationParameters = new TokenValidationParameters + { + ValidateIssuer = false, + ValidateAudience = false, + ValidateLifetime = true, + ClockSkew = TimeSpan.FromSeconds(serverOptions.Api.JWT.ClockSkew), + ValidateIssuerSigningKey = true, + ValidAudience = serverOptions.Api.JWT.ValidAudience, + ValidIssuer = serverOptions.Api.JWT.ValidIssuer, + IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(serverOptions.Api.JWT.IssuerSigningKey)) + }; + + options.Events = new JwtBearerEvents + { + OnChallenge = async context => + { + context.HandleResponse(); + + context.Response.ContentType = "application/json;charset=utf-8"; + context.Response.StatusCode = StatusCodes.Status200OK; + + await context.Response.WriteAsync(new + { + errorCode = 1, + errorMessage = context.Error ?? "Token is Required" + }.ToJson()); + }, + }; + }); + } + + services.AddSingleton(); + }); + } +} diff --git a/FastTunnel.Core/FastTunnel.Core.csproj b/FastTunnel.Core/FastTunnel.Core.csproj index 4cc8ab3..e33ca86 100644 --- a/FastTunnel.Core/FastTunnel.Core.csproj +++ b/FastTunnel.Core/FastTunnel.Core.csproj @@ -18,10 +18,6 @@ true FastTunnel.Core - - - - diff --git a/FastTunnel.Core/Handlers/Server/LoginHandler.cs b/FastTunnel.Core/Handlers/Server/LoginHandler.cs index 702a6e0..8a1215c 100644 --- a/FastTunnel.Core/Handlers/Server/LoginHandler.cs +++ b/FastTunnel.Core/Handlers/Server/LoginHandler.cs @@ -12,6 +12,7 @@ using FastTunnel.Core.Models; using FastTunnel.Core.Models.Massage; using Microsoft.Extensions.Logging; using System; +using System.Collections.Generic; using System.Linq; using System.Text.Json; using System.Threading; @@ -36,6 +37,8 @@ namespace FastTunnel.Core.Handlers.Server { bool hasTunnel = false; + List tips = new List(); + await client.webSocket.SendCmdAsync(MessageType.Log, $"穿透协议 | 映射关系(公网=>内网)", CancellationToken.None); Thread.Sleep(300); @@ -80,6 +83,12 @@ namespace FastTunnel.Core.Handlers.Server { try { + if (item.LocalPort == 3389) + tips.Add("您已将3389端口暴露,请确保您的PC密码足够安全。"); + + if (item.LocalPort == 22) + tips.Add("您已将22端口暴露,请确保您的PC密码足够安全。"); + ForwardInfo old; if (server.ForwardList.TryGetValue(item.RemotePort, out old)) { @@ -116,6 +125,11 @@ namespace FastTunnel.Core.Handlers.Server } } + foreach (var item in tips) + { + await client.webSocket.SendCmdAsync(MessageType.Log, item, CancellationToken.None); + } + if (!hasTunnel) await client.webSocket.SendCmdAsync(MessageType.Log, TunnelResource.NoTunnel, CancellationToken.None); } diff --git a/FastTunnel.Server/Program.cs b/FastTunnel.Server/Program.cs index 307c6c2..d3fd758 100644 --- a/FastTunnel.Server/Program.cs +++ b/FastTunnel.Server/Program.cs @@ -33,6 +33,9 @@ public class Program .UseWindowsService() .ConfigureWebHost(webHostBuilder => { + // Use FastTunnelHostingStartup + webHostBuilder.UseSetting(WebHostDefaults.HostingStartupAssembliesKey, "FastTunnel.Api"); + webHostBuilder.ConfigureAppConfiguration((hostingContext, config) => { var env = hostingContext.HostingEnvironment; diff --git a/FastTunnel.Server/Properties/launchSettings.json b/FastTunnel.Server/Properties/launchSettings.json index 64fd206..33355cb 100644 --- a/FastTunnel.Server/Properties/launchSettings.json +++ b/FastTunnel.Server/Properties/launchSettings.json @@ -14,7 +14,8 @@ "launchBrowser": true, "launchUrl": "http://localhost:1270/swagger", "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" + "ASPNETCORE_ENVIRONMENT": "Development", + //"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "FastTunnel.Api;FastTunnel.Core" }, "applicationUrl": "https://localhost:5001;http://localhost:5000" }, @@ -32,4 +33,4 @@ "useSSL": true } } -} \ No newline at end of file +} diff --git a/FastTunnel.Server/Startup.cs b/FastTunnel.Server/Startup.cs index b4aea36..0a8d789 100644 --- a/FastTunnel.Server/Startup.cs +++ b/FastTunnel.Server/Startup.cs @@ -36,41 +36,6 @@ public class Startup // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { - services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) - .AddJwtBearer(options => - { - var serverOptions = Configuration.GetSection("FastTunnel").Get(); - - options.TokenValidationParameters = new TokenValidationParameters - { - ValidateIssuer = false, - ValidateAudience = false, - ValidateLifetime = true, - ClockSkew = TimeSpan.FromSeconds(serverOptions.Api.JWT.ClockSkew), - ValidateIssuerSigningKey = true, - ValidAudience = serverOptions.Api.JWT.ValidAudience, - ValidIssuer = serverOptions.Api.JWT.ValidIssuer, - IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(serverOptions.Api.JWT.IssuerSigningKey)) - }; - - options.Events = new JwtBearerEvents - { - OnChallenge = async context => - { - context.HandleResponse(); - - context.Response.ContentType = "application/json;charset=utf-8"; - context.Response.StatusCode = StatusCodes.Status200OK; - - await context.Response.WriteAsync(new - { - errorCode = 1, - errorMessage = context.Error ?? "Token is Required" - }.ToJson()); - }, - }; - }); - services.AddAuthorization(); services.AddControllers(); @@ -81,7 +46,6 @@ public class Startup c.SwaggerDoc("v2", new OpenApiInfo { Title = "FastTunel.Api", Version = "v2" }); }); #endif - services.AddSingleton(); // -------------------FastTunnel STEP1 OF 3------------------ services.AddFastTunnelServer(Configuration.GetSection("FastTunnel")); // -------------------FastTunnel STEP1 END------------------- @@ -105,11 +69,9 @@ public class Startup app.UseFastTunnelServer(); // -------------------FastTunnel STEP2 END------------------- - // --------------------- Custom UI ---------------- app.UseStaticFiles(); app.UseAuthentication(); app.UseAuthorization(); - // --------------------- Custom UI ---------------- app.UseEndpoints(endpoints => {