2011-11-29 2 views
9

Recentemente ho avuto un po 'di un problema con un sito su AppHarbor che ho scritto sul loro forum di supporto: Request.IsSecureConnection always returns falseContrassegnare cookie come "sicuro" in forme auth quando il sito è un servizio di bilanciamento del carico che serve il CERT TLS

In breve, poiché il bilanciamento del carico decrittografa il traffico HTTPS prima che raggiunga l'app Web, attributi come Request.IsSecureConnection e la configurazione come requireSSL su auth di moduli non si comportano come previsto. In effetti, in quest'ultimo caso, non è nemmeno possibile autenticare l'app in quanto la richiesta non viene inoltrata tramite HTTPS.

E 'l'autenticazione forme che è particolarmente problematico perché senza di essa, i cookie non sono impostati su "sicuro" e vengono inviati su HTTP se il sito è accessibile da nome di dominio solo e implicitamente serve lo schema URL insicuro.

Quale sarebbe la soluzione migliore per questo? Preferirei sfruttare la configurazione di sicurezza nativa, qualcuno può vedere un modo per sovrascrivere l'implementazione che controlla se la connessione è sicura? E 'abbastanza facile per rilevare se la richiesta è stata servita su HTTPS (sia basato sulla Request.Url.Scheme o l'intestazione X_FORWARDED_FOR), è solo una questione di legare ordinatamente questo.

+0

IsSecureConnection controlla solo se l'url inizia con https: // (e non con http: //) – Aristos

+0

Ne sei sicuro? Sembra esserci di più anche in base alla risposta su App Harbor e ad altre persone che hanno problemi simili nelle stesse circostanze in altri scenari con carico bilanciato. La mia comprensione è che controlla se la connessione utilizza socket sicuri ma non dipende da se lo schema URL è HTTPS, quindi il problema. –

+0

l'ultima volta che ho controllato questo con NetReflector, e vedo il codice di "IsSecureConnection" che controlla solo se url inizia con https: // Se puoi eseguire NetReflector trovi la funzione e controlla tu stesso. – Aristos

risposta

4

disattivare l'impostazione RequireSSL e aggiungere il seguente codice per la vostra applicazione . Questo dovrebbe proteggere i cookie di autenticazione/sessione.

void Application_EndRequest(object sender, EventArgs e) 
{ 
    if (Response.Cookies.Count > 0) 
    { 
     foreach (string s in Response.Cookies.AllKeys) 
     { 
      if (s == FormsAuthentication.FormsCookieName || s.ToLower() == "asp.net_sessionid") 
      { 
       Response.Cookies[s].Secure = true; 
      } 
     } 
    } 
} 
+0

Consentire al cookie di andare su HTTP lo manterrebbe insicuro. Poiché 'Response.Cookies.Count> 0' non è necessario con' foreach', ho finito per scambiarlo con '! Request.IsLocal' e inserire' Response.Cookies [s] .HttpOnly = false; 'per evitare di inviarlo via cavo in testo in chiaro (ma lasciarlo aperto per test di sviluppo locale). – patridge

+0

HttpOnly = false IS THE WRONG FLAG (controlla se il cookie è disponibile per Javascript e non ha nulla a che fare con il tipo di connessione). –

5

In alternativa, è possibile utilizzare il modulo riscrittura URL per ingannare ASP.NET a pensare che è in esecuzione in un contesto di HTTPS, e lasciare le bandiere requireSSL in atto (che significa che i cookie vengono impostati come sicuro - e disponibile solo se si davvero eseguite in HTTPS)

È possibile impostare il seguente nel web.config:

<rewrite> 
     <rules> 
      <rule name="HTTPS_AlwaysOn" patternSyntax="Wildcard"> 
       <match url="*" /> 
       <serverVariables> 
        <set name="HTTPS" value="on" /> 
       </serverVariables> 
       <action type="None" /> 
      </rule> 
     </rules> 
    </rewrite> 

Avrete anche bisogno di aggiungere HTTPS per l'elenco dei allowedServerVariables in l'applicationHost.config (o tramite la riscrittura URL config)

 <rewrite> 
      <allowedServerVariables> 
       <add name="HTTPS" /> 
      </allowedServerVariables> 
     </rewrite> 

Con grazie a Levi Broderick sulla squadra ASP.NET che mi ha mandato nella direzione giusta a questa soluzione!