2.15HttpContext 转发和代理
HttpContext 转发是指在 ASP.NET Core 应用程序中,将一个 HTTP 请求的上下文信息(包括请求标头、请求内容、查询字符串、响应标头、响应内容等)从一个请求转发到另一个内部请求或服务的过程。这种技术允许开发者在不改变客户端请求的情况下,将请求重定向到另一个处理点,从而实现请求的代理或路由功能。
HttpContext 转发是指在 ASP.NET Core 应用程序中,将一个 HTTP 请求的上下文信息(包括请求标头、请求内容、查询字符串、响应标头、响应内容等)从一个请求转发到另一个内部请求或服务的过程。这种技术允许开发者在不改变客户端请求的情况下,将请求重定向到另一个处理点,从而实现请求的代理或路由功能。
HttpContext 转发的应用场景:
API Gateway模式:作为所有外部请求的入口点,将请求路由到正确的后端服务。- 负载均衡和故障转移:将请求转发到其他可用的服务实例,确保系统的稳定性和可靠性。
- 请求日志记录和审计:将请求信息记录到日志系统或审计服务,便于监控和调试。
- 安全过滤和验证:在转发过程中检查请求的认证信息和权限,确保请求的合法性。
- A/B 测试和蓝绿部署:将部分流量路由到新版本的服务,逐步验证新功能。
- 跨域请求处理:处理跨域请求,确保请求能够成功执行。
在使用 HttpContext 进行转发操作之前,请确保已完成以下两个步骤:
- 注册并启用
IHttpContextAccessor服务。
在 Startup.cs 或 Program.cs 文件中注册并启用 IHttpContextAccessor 服务,并配置转发目标白名单。
services.AddHttpContextAccessor(); // 若使用 Furion 框架无需注入(已默认注入)// 全局配置 HttpContext 转发配置选项services.Configure<HttpContextForwardOptions>(options =>{ // 允许转发的目标主机白名单,必须显式配置;若未配置或为空,任何通过 X-Forward-To 头的转发都会被拒绝 options.AllowedHosts = ["*"]; // "*" 表示允许所有主机和协议(高风险,仅推荐在信任环境使用)});AllowedHosts 白名单规则详解:
"furion.net"— 仅主机名,匹配任意协议(http/https)的默认端口(80/443)。"furion.net:8080"— 主机+端口,匹配任意协议的指定端口。"furion.net:*"— 主机+端口通配符,匹配任意协议下的任意端口。"https://furion.net"— 协议+主机,只匹配指定协议的默认端口。"http://furion.net:8080"— 协议+主机+端口,精确匹配。"https://furion.net:*"— 协议+主机+端口通配符,只匹配指定协议的任意端口。"[::1]"—IPv6主机(方括号包裹),匹配任意协议的默认端口。"[::1]:8080"—IPv6主机+端口,匹配任意协议的指定端口。"[::1]:*"—IPv6主机+端口通配符,匹配任意协议下的任意端口。"http://[2001:db8::1]:8080"— 协议+IPv6 主机+端口,精确匹配。"*"— 全局通配符,允许任意主机和协议(完全绕过所有主机验证)。
- 启用请求正文缓存中间件,以支持请求内容的重复读取。
app.UseEnableBuffering();- (可选) 若在转发过程中出现
The SSL connection could not be established, see inner exception.的证书错误问题,您可以通过添加以下配置来忽略SSL证书验证:
// 默认客户端配置services.AddHttpClient(string.Empty) .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler { // 忽略 SSL 证书验证 ServerCertificateCustomValidationCallback = HttpRemoteUtility.IgnoreSslErrors, SslProtocols = HttpRemoteUtility.AllSslProtocols });// 若使用 SocketsHttpHandler,可以通过以下配置来忽略 SSL 证书验证services.AddHttpClient(string.Empty) .ConfigurePrimaryHttpMessageHandler(() => new SocketsHttpHandler() { SslOptions = new SslClientAuthenticationOptions { // 忽略 SSL 证书验证 RemoteCertificateValidationCallback = HttpRemoteUtility.IgnoreSocketSslErrors, EnabledSslProtocols = HttpRemoteUtility.AllSslProtocols }, });以下是一个简单的示例,展示了如何在 ASP.NET Core 中实现 HttpContext 转发:
[ApiController][Route("[controller]/[action]")]public class GetStartController(IHttpRemoteService httpRemoteService, IHttpContextAccessor httpContextAccessor) : ControllerBase{ // 转发代理到网站 [HttpGet] [ResponseCache(NoStore = true, Location = ResponseCacheLocation.None)] // 禁用浏览器缓存 public Task<IActionResult?> ForwardToWebSite() { return httpContextAccessor.HttpContext.ForwardAsResultAsync("https://github.com"); } // 转发代理到图片 [HttpGet] [ResponseCache(NoStore = true, Location = ResponseCacheLocation.None)] // 禁用浏览器缓存 public Task<IActionResult?> ForwardToImage() { return httpContextAccessor.HttpContext.ForwardAsResultAsync( "https://img-s-msn-com.akamaized.net/tenant/amp/entityid/AA1u7RJI.img?w=584&h=326&m=6"); } // 转发代理到下载 [HttpGet] [ResponseCache(NoStore = true, Location = ResponseCacheLocation.None)] // 禁用浏览器缓存 public Task<IActionResult?> ForwardToDownload() { return httpContextAccessor.HttpContext.ForwardAsResultAsync( "https://download.visualstudio.microsoft.com/download/pr/a17b907f-8457-45a8-90db-53f2665ee49e/49bccd33593ebceb2847674fe5fd768e/aspnetcore-runtime-8.0.10-win-x64.exe"); } // 转发代理到表单 [HttpPost] public Task<YourRemoteFormResult?> ForwardToForm(int id, [FromForm] YourRemoteFormModel model) { return httpContextAccessor.HttpContext.ForwardAsAsync<YourRemoteFormResult>( "https://localhost:7044/HttpRemote/AddForm"); }}通过 HttpContext 转发,可以在 ASP.NET Core 应用程序中结合 Middleware 中间件技术实现灵活的请求路由和处理机制,适用于多种应用场景,如 API Gateway、负载均衡、请求日志记录、安全验证等。