Request.Url.Scheme fornisce http invece di https su un sito con bilanciamento del carico

Request.Url.Scheme fornisce http invece di https su un sito con bilanciamento del carico

Come hai detto, la terminazione HTTPS viene eseguita a livello di bilanciamento del carico ("https è impostato a livello di bilanciamento del carico"), il che significa che lo schema originale potrebbe non accedi al sito in base alla configurazione del loadbalancer.

Sembra che nel tuo caso LB sia configurato per comunicare sempre con il sito tramite HTTP. Quindi il tuo sito non vedrà mai lo schema originale su HttpContext.Request.RawUrl (o proprietà simili).

Correzione:di solito quando LB, proxy o CDN sono configurati in questo modo ci sono intestazioni aggiuntive che specificano lo schema originale e probabilmente altri parametri della richiesta in entrata come l'URL completo, l'IP del client che non sarà direttamente visibile al sito dietro tale dispositivo di proxy.


Sostituisco il ServerVariables per convincere MVC sta davvero comunicando tramite HTTPS ed espone anche l'indirizzo IP dell'utente. Questo sta usando il X-Forwarded-For e X-Forwarded-Proto Intestazioni HTTP impostate dal sistema di bilanciamento del carico.

Tieni presente che dovresti usarlo solo se sei veramente sicuro che queste intestazioni siano sotto il tuo controllo, altrimenti i clienti potrebbero iniettare valori di loro gradimento.

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()
    {
    }
}

E in Web.config :

<system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
        <add name="HttpOverrides" type="Namespace.HttpOverrides" preCondition="integratedMode" />
    </modules>
</system.webServer>

So che questa è una vecchia domanda, ma dopo aver riscontrato lo stesso problema, ho scoperto che se guardo nella proprietà UrlReferrer di HttpRequest oggetto, i valori rifletteranno ciò che era effettivamente nella barra degli indirizzi del browser del client.

Ad esempio, con UrlReferrer Ho:

Request.UrlReferrer.Scheme == "https"
Request.UrlReferrer.Port == 443

Ma per la stessa richiesta, con il Url proprietà Ho ottenuto quanto segue:

Request.Url.Scheme == "http"
Request.Url.Port == 80