我正在测试新的负载平衡暂存站点,并且https是在负载均衡器级别设置的,而不是在站点级别.此外,这个网站将始终是https所以我不需要远程需要https属性等.网址显示https但它在我的代码中不可用.由于这个原因,我有一些问题
Request.Url.Scheme总是http:
public static string GetProtocol()
{
var protocol = "http";
if (HttpContext.Current != null && HttpContext.Current.Request != null)
{
protocol = HttpContext.Current.Request.Url.Scheme;
}
return protocol;
}
Run Code Online (Sandbox Code Playgroud)
与此基本URL相同,协议是http
public static string GetBaseUrl()
{
var baseUrl = String.Empty;
if (HttpContext.Current == null || HttpContext.Current.Request == null || String.IsNullOrWhiteSpace(HttpRuntime.AppDomainAppPath)) return baseUrl;
var request = HttpContext.Current.Request;
var appUrl = HttpRuntime.AppDomainAppVirtualPath;
baseUrl = string.Format("{0}://{1}{2}", request.Url.Scheme, request.Url.Authority, appUrl);
if (!string.IsNullOrWhiteSpace(baseUrl) && !baseUrl.EndsWith("/"))
baseUrl = String.Format("{0}/", baseUrl);
return baseUrl;
}
Run Code Online (Sandbox Code Playgroud)
现在最大的问题是引用样式表中引用的js文件和谷歌字体.我在这里使用//没有http或https,但这些被视为http,我在FireBug中看到混合内容被阻止的消息.
我怎样才能克服这个问题?
Ale*_*kov 16
正如您所说,HTTPS终止是在负载均衡器级别完成的("https是在负载均衡器级别设置的"),这意味着原始方案可能不会到达站点,具体取决于负载均衡器配置.
看起来在您的情况下,LB配置为始终通过HTTP与站点通信.因此,您的网站永远不会看到原始方案HttpContext.Request.RawUrl
(或类似的属性).
修复:通常当LB,代理或CDN以这种方式配置时,会有额外的标头指定原始方案以及可能的其他传入请求参数,例如完整URL,客户端的IP,这些代理设备后面的站点将不会直接看到.
我覆盖ServerVariables
以说服 MVC 它确实是通过 HTTPS 进行通信并公开用户的 IP 地址。这是使用负载均衡器设置的X-Forwarded-For
和X-Forwarded-Proto
HTTP 标头。
请注意,如果您真的确定这些标头在您的控制之下,您应该只使用它,否则客户端可能会注入他们喜欢的值。
public sealed class HttpOverrides : IHttpModule
{
void IHttpModule.Init(HttpApplication app)
{
app.BeginRequest += OnBeginRequest;
}
private void OnBeginRequest(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication)sender;
string forwardedFor = app.Context.Request.Headers["X-Forwarded-For"]?.Split(new char[] { ',' }).FirstOrDefault();
if (forwardedFor != null)
{
app.Context.Request.ServerVariables["REMOTE_ADDR"] = forwardedFor;
app.Context.Request.ServerVariables["REMOTE_HOST"] = forwardedFor;
}
string forwardedProto = app.Context.Request.Headers["X-Forwarded-Proto"];
if (forwardedProto == "https")
{
app.Context.Request.ServerVariables["HTTPS"] = "on";
app.Context.Request.ServerVariables["SERVER_PORT"] = "443";
app.Context.Request.ServerVariables["SERVER_PORT_SECURE"] = "1";
}
}
void IHttpModule.Dispose()
{
}
}
Run Code Online (Sandbox Code Playgroud)
并在Web.config
:
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="HttpOverrides" type="Namespace.HttpOverrides" preCondition="integratedMode" />
</modules>
</system.webServer>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
22082 次 |
最近记录: |