如何配置app.UseHttpsRedirection()重定向至请求主机而非底层主机?
这个问题的核心是**app.UseHttpsRedirection()默认使用App Service的底层主机名生成重定向URL**,而没有识别到Akamai CDN传递过来的原始请求主机名。下面是具体的解决步骤:
1. 启用转发头中间件,让App Service识别原始请求信息
因为请求先经过Akamai CDN再到达App Service,App Service需要信任CDN传递的转发头(比如X-Forwarded-Host、X-Forwarded-Proto),才能获取到真实的客户端请求主机名和协议。
在Startup.cs的ConfigureServices中配置转发头选项,然后在Configure中**提前于UseHttpsRedirection**调用UseForwardedHeaders:
public void ConfigureServices(IServiceCollection services) { // 配置信任转发头,包含主机名、协议等信息 services.Configure<ForwardedHeadersOptions>(options => { options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost; // Azure App Service默认会信任前端的代理,不需要额外添加KnownProxies }); // 其他服务配置... } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // 必须在UseHttpsRedirection之前执行,确保后续中间件能拿到正确的请求信息 app.UseForwardedHeaders(); // 原有的HttpsRedirection app.UseHttpsRedirection(); // 其他中间件(路由、授权等)... app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
2. 自定义HttpsRedirection的重定向逻辑,强制使用原始主机名
有时候即使启用了转发头,默认的HttpsRedirectionMiddleware还是会使用App Service的默认域名,这时候需要自定义重定向逻辑,直接读取X-Forwarded-Host头来生成目标URL:
在ConfigureServices中添加AddHttpsRedirection的配置:
public void ConfigureServices(IServiceCollection services) { // ... 前面的转发头配置 ... services.AddHttpsRedirection(options => { options.RedirectStatusCode = StatusCodes.Status301MovedPermanently; // 可选,用永久重定向利于SEO options.HttpsPort = 443; // 自定义重定向逻辑,替换主机名为原始请求的主机名 options.OnRedirect = context => { var originalHost = context.HttpContext.Request.Headers["X-Forwarded-Host"].FirstOrDefault(); if (!string.IsNullOrEmpty(originalHost)) { var uriBuilder = new UriBuilder(context.RedirectUri); uriBuilder.Host = originalHost; context.RedirectUri = uriBuilder.Uri.ToString(); } return Task.CompletedTask; }; }); // ... 其他服务配置 ... }
3. 验证Akamai CDN是否传递必要的转发头
确保Akamai CDN已经配置为向App Service传递X-Forwarded-Host和X-Forwarded-Proto头。虽然标准版Akamai CDN没有规则引擎,但默认通常会传递这些头;如果没有的话,需要联系Akamai支持确认配置。
备选方案:使用URL重写中间件直接处理重定向
如果觉得上面的配置麻烦,也可以绕过默认的UseHttpsRedirection,用UseRewriter自己实现HTTP到HTTPS的重定向,确保使用原始主机名:
public void ConfigureServices(IServiceCollection services) { services.AddRewrite(); // ... 其他服务配置 ... } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseForwardedHeaders(); var rewriteOptions = new RewriteOptions() .Add(context => { var request = context.HttpContext.Request; // 检查原始请求是否为HTTP if (request.Headers["X-Forwarded-Proto"] == "http") { var originalHost = request.Headers["X-Forwarded-Host"].FirstOrDefault() ?? request.Host.Host; var redirectUrl = $"https://{originalHost}{request.Path}{request.QueryString}"; context.HttpContext.Response.Redirect(redirectUrl, permanent: true); } }); app.UseRewriter(rewriteOptions); // ... 其他中间件 ... }
这样配置后,当用户访问http://mydns.mycoolserver.com时,就会正确重定向到https://mydns.mycoolserver.com,而不是App Service的默认域名了。
内容的提问来源于stack exchange,提问作者ubienewbie

