.NET Framework 相当于 IApplicationBuilder.UseForwardedHeaders()
.NET Framework equivalent of IApplicationBuilder.UseForwardedHeaders()
我正在 .NET Framework 4.7.2 上使用 ASP.NET WebForms 应用程序 运行,它位于 Azure 应用程序网关后面。网关执行 SSL hand-off 所以正在添加 X-Forwarded-Proto="https"
header.
我还有一个 .NET Core API,我可以在其中配置
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseForwardedHeaders();
app.UseHsts();
app. //...
}
这已记录在案 here,但特定于 .NET Core。
我找不到 .NET Framework 的 UseForwardedHeaders
等效项 - 有等效项吗?
此外,WebForms 应用程序是 运行 在 OWIN 上,所以我可以做这样的事情,但我不确定如何完成它。
public void Configuration(IAppBuilder app)
{
app.Use(async (context, next) =>
{
var forwardedProto = context.Request.Headers["X-Forwarded-Proto"];
if (forwardedProto.ToLower() == "https")
{
// what now?
}
await next();
});
}
是否有针对 .NET Framework 的 out-of-the-box 解决方案,或者关于如何最好地处理这个问题的建议?
我最终构建了自己的中间件。
public static class UseForwardedHeadersExtension
{
private const string ForwardedHeadersAdded = "ForwardedHeadersAdded";
/// <summary>
/// Checks for the presence of <c>X-Forwarded-For</c> and <c>X-Forwarded-Proto</c> headers, and if present updates the properties of the request with those headers' details.
/// </summary>
/// <remarks>
/// This extension method is needed for operating our website on an HTTP connection behind a proxy which handles SSL hand-off. Such a proxy adds the <c>X-Forwarded-For</c>
/// and <c>X-Forwarded-Proto</c> headers to indicate the nature of the client's connection.
/// </remarks>
public static IAppBuilder UseForwardedHeaders(this IAppBuilder app)
{
if (app == null)
{
throw new ArgumentNullException(nameof(app));
}
// No need to add more than one instance of this middleware to the pipeline.
if (!app.Properties.ContainsKey(ForwardedHeadersAdded))
{
app.Properties[ForwardedHeadersAdded] = true;
app.Use(async (context, next) =>
{
var request = context.Request;
if (request.Scheme != Uri.UriSchemeHttps && String.Equals(request.Headers["X-Forwarded-Proto"], Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase))
{
var httpContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName);
var serverVars = httpContext.Request.ServerVariables;
serverVars["HTTPS"] = "on";
serverVars["SERVER_PORT_SECURE"] = "1";
serverVars["SERVER_PORT"] = "443";
serverVars["HTTP_HOST"] = request.Headers.ContainsKey("X-Forwarded-Host") ? request.Headers["X-Forwarded-Host"] : serverVars["HTTP_HOST"];
}
await next.Invoke().ConfigureAwait(false);
});
}
return app;
}
}
我正在 .NET Framework 4.7.2 上使用 ASP.NET WebForms 应用程序 运行,它位于 Azure 应用程序网关后面。网关执行 SSL hand-off 所以正在添加 X-Forwarded-Proto="https"
header.
我还有一个 .NET Core API,我可以在其中配置
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseForwardedHeaders();
app.UseHsts();
app. //...
}
这已记录在案 here,但特定于 .NET Core。
我找不到 .NET Framework 的 UseForwardedHeaders
等效项 - 有等效项吗?
此外,WebForms 应用程序是 运行 在 OWIN 上,所以我可以做这样的事情,但我不确定如何完成它。
public void Configuration(IAppBuilder app)
{
app.Use(async (context, next) =>
{
var forwardedProto = context.Request.Headers["X-Forwarded-Proto"];
if (forwardedProto.ToLower() == "https")
{
// what now?
}
await next();
});
}
是否有针对 .NET Framework 的 out-of-the-box 解决方案,或者关于如何最好地处理这个问题的建议?
我最终构建了自己的中间件。
public static class UseForwardedHeadersExtension
{
private const string ForwardedHeadersAdded = "ForwardedHeadersAdded";
/// <summary>
/// Checks for the presence of <c>X-Forwarded-For</c> and <c>X-Forwarded-Proto</c> headers, and if present updates the properties of the request with those headers' details.
/// </summary>
/// <remarks>
/// This extension method is needed for operating our website on an HTTP connection behind a proxy which handles SSL hand-off. Such a proxy adds the <c>X-Forwarded-For</c>
/// and <c>X-Forwarded-Proto</c> headers to indicate the nature of the client's connection.
/// </remarks>
public static IAppBuilder UseForwardedHeaders(this IAppBuilder app)
{
if (app == null)
{
throw new ArgumentNullException(nameof(app));
}
// No need to add more than one instance of this middleware to the pipeline.
if (!app.Properties.ContainsKey(ForwardedHeadersAdded))
{
app.Properties[ForwardedHeadersAdded] = true;
app.Use(async (context, next) =>
{
var request = context.Request;
if (request.Scheme != Uri.UriSchemeHttps && String.Equals(request.Headers["X-Forwarded-Proto"], Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase))
{
var httpContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName);
var serverVars = httpContext.Request.ServerVariables;
serverVars["HTTPS"] = "on";
serverVars["SERVER_PORT_SECURE"] = "1";
serverVars["SERVER_PORT"] = "443";
serverVars["HTTP_HOST"] = request.Headers.ContainsKey("X-Forwarded-Host") ? request.Headers["X-Forwarded-Host"] : serverVars["HTTP_HOST"];
}
await next.Invoke().ConfigureAwait(false);
});
}
return app;
}
}