Il browser non imposta il cookie ASP.NET_SessionId su richiesta post del gateway di pagamento sul nostro sito


12

Stiamo riscontrando uno strano problema con il processo di pagamento della nostra applicazione Web che comporta la perdita dei dati della sessione.

In questo processo, dopo che la nostra pagina di check-out viene reindirizzato alla pagina del provider di pagamento e reindirizzato al nostro sito (a un URL che specifichiamo) non appena ha finito lì. Quest'ultimo reindirizzamento viene effettuato mediante la valutazione del browser del codice html del provider di pagamento che sostanzialmente consiste in un modulo che pubblica sul nostro sito e in alcune righe di codice javascript che pubblicano quel modulo al caricamento della pagina. A questo punto il browser effettua la richiesta di post ma non imposta il cookie "ASP.NET_SessionId" che è presente nelle precedenti richieste fatte allo stesso dominio (il dominio della nostra applicazione). La cosa più strana è che imposta un altro cookie che usiamo chiamato "AcceptCookie". Scegli semplicemente di eliminare il cookie "ASP.NET_SessionId".

Per illustrare la situazione ho preso alcuni screenshot. (In questi screenshot i rettangoli arancioni e verdi contengono esattamente lo stesso valore.)

  1. Questa è la richiesta presentata (alla nostra applicazione) quando l'utente preme il pulsante "Check out". Dopo questa richiesta, l'utente viene reindirizzato alla pagina del provider di pagamento.

richiesta di check-out

  1. Questa è la pagina finale che viene fornita dal fornitore di pagamenti dopo che l'utente ha effettuato lì. Come puoi vedere è solo un semplice modulo che viene automaticamente pubblicato sul nostro dominio al caricamento della pagina.

risposta finale del fornitore di servizi di pagamento

  1. Ma questa richiesta di post non include il cookie "ASP.NET_SessionId" che comporta l'acquisizione di un nuovo ID sessione e la perdita dei dati della sessione precedente. E ancora, manca solo "ASP.NET_SessionId", non l'altro chiamato "AcceptCookie".

invia una richiesta che riporta l'utente al nostro sito (fatto con javascript nel passaggio precedente)

Alla fine abbiamo capito che nelle versioni precedenti dei browser questo problema non si verifica. Su Firefox 52 funziona come un fascino, ma su Firefox 71 si verifica il problema precedente.

Qualche idea?

Nota: si tratta di un'applicazione ASP.NET MVC con targetFramework = "4.5.2"

Buona giornata.

Risposte:


16

L'abbiamo capito.

In qualche modo l'attributo "SameSite" del cookie "ASP.NET_SessionId" viene impostato automaticamente su "Lax" e ciò causa l'aggiunta del cookie di sessione alla richiesta effettuata dal codice javascript del gateway di pagamento.

Abbiamo aggiunto la seguente regola al file web.config per sovrascrivere questo valore e impostarlo su "Nessuno".

<configuration>
  <system.webServer>
    <rewrite>
      <outboundRules>
        <rule name="Add SameSite" preCondition="No SameSite">
          <match serverVariable="RESPONSE_Set_Cookie" pattern=".*" negate="false" />
          <action type="Rewrite" value="{R:0}; SameSite=None" />
          <conditions>
          </conditions>
        </rule>
        <preConditions>
          <preCondition name="No SameSite">
            <add input="{RESPONSE_Set_Cookie}" pattern="." />
            <add input="{RESPONSE_Set_Cookie}" pattern="; SameSite=None" negate="true" />
          </preCondition>
        </preConditions>
      </outboundRules>
    </rewrite>
  </system.webServer>
</configuration>

AGGIORNAMENTO 1 : L'aggiunta della precedente configurazione ha risolto il problema per i browser moderni ma ci siamo resi conto che c'erano ancora problemi con le versioni precedenti di Micosoft Edge e Internet Explorer.

Quindi abbiamo dovuto aggiungere l'attributo cookieSameSite = "None" al nodo sessionState nel file web.config.

<sessionState cookieSameSite="None" />

Prestare attenzione a questa modifica della configurazione, poiché le versioni precedenti del framework .net non lo supportano e fanno in modo che il sito visualizzi la pagina di errore.

A proposito, stiamo ancora riscontrando problemi con i browser in IOS 12. Ma penso che sia correlato a questo bug confermato

AGGIORNAMENTO 2 : vedere la risposta di zemien per la possibile correzione del problema IOS

AGGIORNAMENTO 3 : Combinando le nostre scoperte con i suggerimenti nella risposta di Zemien, abbiamo creato le seguenti regole di riscrittura. Abbiamo usato questa configurazione in produzione. Ma attenzione: contrassegna tutti i cookie con l'attributo "SameSite: Nessuno" per i browser compatibili ed esclude, se esiste, l'attributo SameSite per i browser incompatibili. Può sembrare complicato ma ho cercato di spiegare tramite le righe di commento.

Questa è la configurazione FINALE che usiamo in produzione:

<configuration> 

  <system.webServer>

    <rewrite>

      <outboundRules>

        <preConditions>
          <!-- Browsers incompatible with SameSite=None -->
          <preCondition name="IncompatibleWithSameSiteNone" logicalGrouping="MatchAny">
            <add input="{HTTP_USER_AGENT}" pattern="(CPU iPhone OS 12)|(iPad; CPU OS 12)" />
            <add input="{HTTP_USER_AGENT}" pattern="(Chrome/5)|(Chrome/6)" />
            <add input="{HTTP_USER_AGENT}" pattern="( OS X 10_14).*(Version/).*((Safari)|(KHTML, like Gecko)$)" />
          </preCondition>

          <!-- Rest of the browsers are assumed to be compatible with SameSite=None -->
          <preCondition name="CompatibleWithSameSiteNone" logicalGrouping="MatchAll">
            <add input="{HTTP_USER_AGENT}" pattern="(CPU iPhone OS 12)|(iPad; CPU OS 12)" negate="true" />
            <add input="{HTTP_USER_AGENT}" pattern="(Chrome/5)|(Chrome/6)" negate="true" />
            <add input="{HTTP_USER_AGENT}" pattern="( OS X 10_14).*(Version/).*((Safari)|(KHTML, like Gecko)$)" negate="true" />
          </preCondition>

        </preConditions>

        <!-- Rule 1: Remove SameSite part from cookie for incompatible browsers if exists -->
        <rule name="Remove_SameSiteCookie_IfExists_ForLegacyBrowsers" preCondition="IncompatibleWithSameSiteNone">
          <match serverVariable="RESPONSE_Set-Cookie" pattern="(.*)(SameSite=.*)" />
          <action type="Rewrite" value="{R:1}" />
        </rule>

        <!-- Rule 2: Override SameSite's value to None if exists, for compatible browsers -->
        <rule name="Override_SameSiteCookie_IfExists_ForModernBrowsers" preCondition="CompatibleWithSameSiteNone">
          <match serverVariable="RESPONSE_Set-Cookie" pattern="(.*)(SameSite=.*)" />
          <action type="Rewrite" value="{R:1}; SameSite=None" />
        </rule>

        <!-- Rule 3: Add SameSite attribute with the value None if it does not exists, for compatible browsers -->
        <rule name="Add_SameSiteCookie_IfNotExists_ForModernBrowsers" preCondition="CompatibleWithSameSiteNone">
          <match serverVariable="RESPONSE_Set-Cookie" pattern=".*"/>
          <!-- Condition explanation: Cookie data contains some string value but does not contain SameSite attribute -->
          <conditions logicalGrouping="MatchAll">
            <add input="{R:0}" pattern="^(?!\s*$).+"/>
            <add input="{R:0}" pattern="SameSite=.*" negate="true"/>
          </conditions>
          <action type="Rewrite" value="{R:0}; SameSite=None" />
        </rule>

      </outboundRules>

    </rewrite>    

  </system.webServer>  

</configuration>

Grazie @ EÖzgür. Questo problema proviene da KB4533097 ( support.microsoft.com/en-us/help/4533097/kb4533097 ) in particolare KB4533011 (.net 4.7 e precedenti) e KB4533004 (.net 4.8) rilasciato il 10 dicembre
S. Pineau

Ho lo stesso problema, ma a volte asp.net mvc fornisce al cliente ASP.NET_SessionId cookie con LAX a volte con NESSUNO. Non sono sicuro del perché accada. Voglio dire, dovrebbe essere sempre LAX, ma quando accedo al sito non riesco a trovare NESSUNO.
Duca il

Oddio! Sono stato pazzo di questo problema per due giorni. Finalmente la tua risposta mi ha salvato la giornata e la frustrazione. Grazie.
Hemanth,

1
Abbiamo riscontrato questo problema nel Server 2016 dopo l'applicazione degli aggiornamenti di dicembre. (KB4530689). Mille grazie per aver trovato la soluzione!
user0474975

È solo per il core dotnet? Nella mia applicazione Framework sto mostrando quelle opzioni come valori non validi da impostare.
IronSean,

3

Ho modificato diverse risposte SO per creare questa riscrittura URL che si aggiunge SameSite=Noneai cookie di sessione e rimuove anche SameSite=Noneda tutti cookie per la maggior parte dei browser incompatibili. Lo scopo di questa riscrittura è preservare il comportamento "legacy" pre-Chrome 80.

Scrittura completa nel mio blog Coder Frontline :

<rewrite>
  <outboundRules>
    <preConditions>
      <!-- Checks User Agent to identify browsers incompatible with SameSite=None -->
      <preCondition name="IncompatibleWithSameSiteNone" logicalGrouping="MatchAny">
        <add input="{HTTP_USER_AGENT}" pattern="(CPU iPhone OS 12)|(iPad; CPU OS 12)" />
        <add input="{HTTP_USER_AGENT}" pattern="(Chrome/5)|(Chrome/6)" />
        <add input="{HTTP_USER_AGENT}" pattern="( OS X 10_14).*(Version/).*((Safari)|(KHTML, like Gecko)$)" />
      </preCondition>
    </preConditions>

    <!-- Adds or changes SameSite to None for the session cookie -->
    <!-- Note that secure header is also required by Chrome and should not be added here -->
    <rule name="SessionCookieAddNoneHeader">
      <match serverVariable="RESPONSE_Set-Cookie" pattern="((.*)(ASP.NET_SessionId)(=.*))(SameSite=.*)?" />
      <action type="Rewrite" value="{R:1}; SameSite=None" />
    </rule>

    <!-- Removes SameSite=None header from all cookies, for most incompatible browsers -->
    <rule name="CookieRemoveSameSiteNone" preCondition="IncompatibleWithSameSiteNone">
      <match serverVariable="RESPONSE_Set-Cookie" pattern="(.*)(SameSite=None)" />
      <action type="Rewrite" value="{R:1}" />
    </rule>
  </outboundRules>
</rewrite>

Questo dovrebbe funzionare per la maggior parte delle applicazioni ASP .Net e ASP .Net Core, sebbene i Frameworks più recenti abbiano codice e opzioni di configurazione adeguati per consentire il controllo di questo comportamento. Consiglierei di ricercare tutte le opzioni disponibili prima di usare la mia riscrittura sopra.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.