2016-02-17 23 views
9

Ho due siti Web IIS impostati sullo stesso server IIS. Il sito Web A contiene la maggior parte del contenuto e questo è ciò che gli utenti vengono mostrati quando richiedono il nostro indirizzo (ad esempio www.websitea.com). Il sito Web B è un progetto separato che contiene solo una parte dell'intero contenuto, quindi è interno (associato a IIS a websiteb.com), ma tramite un URL riscritto, gli utenti possono raggiungerlo digitando www.websitea.com/websiteb .Tentativo di reindirizzamento da HTTP a HTTPS (C#, IIS), ma HTTPS torna a HTTP nelle intestazioni di risposta - ciclo di reindirizzamento

La riscrittura URL simile a questa nel web.config sito web di A:

<rewrite> 
    <rules> 
    <clear /> 
    <rule name="Website B rewrite rule" stopProcessing="true"> 
     <match url="^websiteb(.*)" /> 
     <conditions logicalGrouping="MatchAll" trackAllCaptures="false"> 
     <add input="{CACHE_URL}" pattern="^(https?)://" /> 
     </conditions> 
     <action type="Rewrite" url="{C:1}://websiteb.com{R:1}" /> 
    </rule> 
    </rules> 
</rewrite> 

La {CACHE_URL} e {C: 1} bit sono per mantenere il protocollo utilizzato. Per esempio. un utente che richiede www.websitea.com/websiteb/foo.html su HTTP viene "riscritto" su websiteb.com/foo.html su HTTP e una richiesta a websitea.com/websiteb/bar.html su HTTPS viene "riscritta" a websiteb.com/bar.html su HTTPS.

Ora, per alcune pagine del sito Web B vogliamo che l'utente utilizzi solo HTTPS - questo è impostato nella proprietà ShouldBeHttps di SomePageViewModel. Così il seguente codice viene utilizzato in un ActionFilterAttribute:

public override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
     if (filterContext.HttpContext.Request.IsSecureConnection) 
      return; 

     var result = filterContext.Result as ViewResult; 
     if (result != null) 
     { 
      if ((result.Model as SomePageViewModel).ShouldBeHttps) 
      { 
       HandleNonHttpsRequest(filterContext); 
      } 
     } 
    } 

    protected virtual void HandleNonHttpsRequest(ActionExecutedContext filterContext) 
    { 
     if (!string.Equals(filterContext.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase)) 
      throw new InvalidOperationException("The method must be a GET"); 
     string url = filterContext.HttpContext.Request.Url.ToString().Replace("http:", "https:"); 
     filterContext.Result = new RedirectResult(url); 
    } 

Diciamo www.websitea.com/websiteb/securepage.html si tradurrà in un vero e proprio valore nella proprietà ShouldBeHttps.

Ora, quando eseguo il test direttamente sul server andando su websiteb.com/securepage.html su HTTP, vengono reindirizzati correttamente (codice di stato 302) a websiteb.com/securepage.html su HTTPS.

Mi aspetto che quando vado a www.websitea.com/websiteb/securepage.html su HTTP, sarò reindirizzato a www.websitea.com/websiteb/securepage.html su HTTPS. Tuttavia, i miei browser finiscono in un ciclo di reindirizzamento (ERR_TOO_MANY_REDIRECTS). Posso vedere in Fiddler in scheda TextView che sembra essere correttamente impostato:

<html> 
<head> 
    <title>Object moved</title> 
</head> 
<body> 
<h2>Object moved to <a href="https://www.websitea.com/websiteb/securepage.html">here</a>.</h2> 
</body> 
</html> 

Ma la scheda intestazioni mostra:

Response Headers 
HTTP/1.1 302 Found 
(...) 
Transport 
    Location: http://www.websitea.com/websiteb/securepage.html 

Così, invece di andare a https, è di nuovo http e che colpisce di nuovo il filtro, e così via.

C'è qualcosa che mi manca? Sono alcune impostazioni IIS?

+0

credo che il problema è la regola di riscrittura non vede la differenza b tra una chiamata http o https in arrivo, quindi la riscriverà a https. – Quintium

+0

Credo che funzioni OK, posso vedere le richieste su HTTPS www.websitea.com/websiteb/index.html correttamente andando su HTTPS websiteb.com/index.html e HTTP a HTTP; La proprietà IsSecureConnection su HttpContext.Current.Request è impostata su true/false correttamente. – patrykgliwinski

+0

Ah. Io vedo. Ho interpretato male quella parte. Ma se vuoi reindirizzare websitea a websiteb nella regola di riscrittura, non dovrebbe Essere Invece? – Quintium

risposta

-1

Prova questa configurazione. Opere per il mio sito web

<rule name="Redirect to HTTPS" stopProcessing="true"> 
<match url="(.*)" /> 
<conditions><add input="{HTTPS}" pattern="^OFF$" /> 
</conditions> 
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="SeeOther" /> 
</rule> 
+0

No, no, ho bisogno di usare quel valore ShouldBeHttps, che è "calcolato" sul lato server solo dopo che è stata eseguita la riscrittura, quindi non posso "hard-code "https nell'azione di riscrittura. – patrykgliwinski

-1

Questo è principalmente un bug in IIS

1.Disable l'URL Rewrite cache

2.Add una variabile "non sicuro" per la regola

3.Svuota la cache

E modo migliore, se è possibile farlo nel codice senza usare Riscrivere

seconda di cosa si versione utilizzando di IIS, questo potrebbe risolvere il tuo problema:

x64

x86

KB2974666