如何在.NET Framework 4.7.2中实现带凭证HTTP代理转无凭证内部代理
实现带凭证HTTP代理的本地中转代理(.NET Framework 4.7.2)
核心逻辑
用HttpListener启动本地无凭证HTTP代理,接收客户端请求后自动转发到带用户名密码的目标HTTP代理,全程对客户端隐藏目标代理的认证信息。
完整实现代码
using System; using System.Net; using System.Net.Http; using System.Threading.Tasks; public class HttpProxyForwarder { private readonly HttpListener _localListener; private readonly HttpClient _forwardClient; // 传入带凭证的目标HTTP代理(格式:username:password@host:port) public HttpProxyForwarder(string targetProxyWithCredentials) { var proxyUri = new Uri($"http://{targetProxyWithCredentials}"); var targetProxyAddr = $"http://{proxyUri.Host}:{proxyUri.Port}"; // 配置带凭证的转发客户端 var handler = new HttpClientHandler { Proxy = new WebProxy(targetProxyAddr) { Credentials = new NetworkCredential( proxyUri.UserInfo.Split(':')[0], proxyUri.UserInfo.Split(':')[1] ) }, UseProxy = true, AllowAutoRedirect = false }; _forwardClient = new HttpClient(handler); _localListener = new HttpListener(); // 绑定本地随机可用端口 _localListener.Prefixes.Add("http://127.0.0.1:0/"); } // 启动本地代理 public async Task StartAsync() { _localListener.Start(); Console.WriteLine($"本地代理已启动:{_localListener.Endpoint}"); // 循环处理客户端请求 while (_localListener.IsListening) { var context = await _localListener.GetContextAsync(); _ = ProcessRequestAsync(context); // 异步处理,不阻塞主线程 } } // 停止代理 public void Stop() { _localListener.Stop(); _forwardClient.Dispose(); } // 处理请求转发逻辑 private async Task ProcessRequestAsync(HttpListenerContext context) { var clientReq = context.Request; var clientResp = context.Response; try { // 构建转发请求 using var forwardReq = new HttpRequestMessage( new HttpMethod(clientReq.HttpMethod), clientReq.Url ); // 复制客户端请求头 foreach (string header in clientReq.Headers) { if (!forwardReq.Headers.TryAddWithoutValidation(header, clientReq.Headers[header]) && !forwardReq.Content?.Headers.TryAddWithoutValidation(header, clientReq.Headers[header]) ?? false) { // 忽略无法添加的头部 } } // 复制请求体(如果存在) if (clientReq.HasEntityBody) { using var reqStream = clientReq.InputStream; forwardReq.Content = new StreamContent(reqStream); } // 发送请求到目标代理 var forwardResp = await _forwardClient.SendAsync(forwardReq, HttpCompletionOption.ResponseHeadersRead); // 将响应返回给客户端 clientResp.StatusCode = (int)forwardResp.StatusCode; foreach (var header in forwardResp.Headers) { clientResp.Headers.Add(header.Key, header.Value); } foreach (var header in forwardResp.Content.Headers) { clientResp.Headers.Add(header.Key, header.Value); } using var respStream = await forwardResp.Content.ReadAsStreamAsync(); await respStream.CopyToAsync(clientResp.OutputStream); } catch (Exception ex) { clientResp.StatusCode = (int)HttpStatusCode.BadGateway; var errorBytes = System.Text.Encoding.UTF8.GetBytes(ex.Message); clientResp.OutputStream.Write(errorBytes, 0, errorBytes.Length); } finally { clientResp.Close(); } } } // 使用示例 class Program { static async Task Main(string[] args) { // 替换为你的带凭证目标HTTP代理 var targetProxy = "username:password@201.202.203.204:2345"; var proxyForwarder = new HttpProxyForwarder(targetProxy); await proxyForwarder.StartAsync(); Console.WriteLine("按任意键停止代理..."); Console.ReadKey(); proxyForwarder.Stop(); } }
关键说明
- 本地端口分配:通过
http://127.0.0.1:0/绑定,系统自动分配随机可用端口,启动后可通过_localListener.Endpoint获取实际地址。 - 凭证处理:自动解析目标代理的
UserInfo部分,提取用户名密码注入转发客户端,对客户端完全隐藏认证信息。 - 请求转发:完整复制客户端的请求方法、URL、头部和请求体,转发后将目标代理的响应原样返回。
- 异步处理:基于
async/await实现非阻塞请求处理,支持多客户端并发访问。
注意事项
- 项目需引用
System.Net.Http和System程序集。 - 若需支持HTTPS转发,可扩展代码处理
CONNECT方法,或为HttpListener配置HTTPS证书。 - 可根据需求扩展异常处理逻辑,比如添加日志记录。
内容的提问来源于stack exchange,提问作者NewbieAsker
相关产品推荐
相关产品推荐

