Der Browser setzt das ASP.NET_SessionId-Cookie nicht auf die Post-Anfrage des Zahlungsgateways auf unserer Website

12

Wir haben ein seltsames Problem mit dem Zahlungsvorgang unserer Webanwendung, das zum Verlust von Sitzungsdaten führt.

In diesem Prozess wird der Benutzer nach dem Auschecken auf die Seite des Zahlungsanbieters weitergeleitet und auf unsere Website (zu einer von uns angegebenen URL) zurückgeleitet, sobald er dort fertig ist. Diese letzte Weiterleitung erfolgt durch die Auswertung des HTML-Codes des Zahlungsanbieters durch den Browser, der im Wesentlichen aus einem Formular besteht, das auf unserer Website veröffentlicht wird, und einigen Zeilen Javascript-Code, der dieses Formular beim Laden der Seite veröffentlicht. Zu diesem Zeitpunkt stellt der Browser die Post-Anfrage, setzt jedoch nicht das Cookie "ASP.NET_SessionId", das in den vorherigen Anfragen an genau dieselbe Domain (die Domain unserer Anwendung) vorhanden ist. Was noch seltsamer ist, ist, dass es ein anderes Cookie setzt, das wir verwenden und das "AcceptCookie" heißt. Es wird einfach das Cookie "ASP.NET_SessionId" gelöscht.

Um die Situation zu veranschaulichen, habe ich einige Screenshots gemacht. (In diesen Screenshots enthalten orange und grüne Rechtecke genau den gleichen Wert.)

  1. Dies ist die Anfrage, die (an unsere Anwendung) gestellt wurde, wenn der Benutzer die Schaltfläche "Auschecken" drückt. Nach dieser Anfrage wird der Benutzer zur Seite des Zahlungsanbieters weitergeleitet.

Check-out-Anfrage

  1. Dies ist die letzte Seite, die vom Zahlungsanbieter bereitgestellt wird, nachdem der Benutzer dort fertig ist. Wie Sie sehen, handelt es sich nur um ein einfaches Formular, das beim Laden der Seite automatisch auf unserer Domain veröffentlicht wird.

endgültige Antwort des Zahlungsanbieters

  1. Diese Post-Anfrage enthält jedoch kein "ASP.NET_SessionId" -Cookie, das zum Abrufen einer neuen Sitzungs-ID und zum Verlust vorheriger Sitzungsdaten führt. Und wieder fehlt nur "ASP.NET_SessionId", nicht die andere mit dem Namen "AcceptCookie".

Post-Anfrage, die den Benutzer zurück auf unsere Website bringt (im vorherigen Schritt mit Javascript erstellt)

Schließlich haben wir festgestellt, dass dieses Problem bei älteren Browserversionen nicht auftritt. Auf Firefox 52 funktioniert es wie ein Zauber, aber auf Firefox 71 tritt das obige Problem auf.

Irgendwelche Ideen?

Hinweis: Es handelt sich um eine ASP.NET MVC-Anwendung mit targetFramework = "4.5.2".

Einen schönen Tag noch.

E. Özgür
quelle

Antworten:

16

Wir haben es herausgefunden.

Irgendwie ist das Attribut "SameSite" des Cookies "ASP.NET_SessionId" standardmäßig "Lax", und dies führt dazu, dass der Anforderung, die vom Javascript-Code des Zahlungsgateways gestellt wird, kein Sitzungscookie hinzugefügt wird.

Wir haben der Datei web.config die folgende Regel hinzugefügt, um diesen Wert zu überschreiben und auf "Keine" zu setzen.

<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>

UPDATE 1 : Nur das Hinzufügen der obigen Konfiguration löste das Problem für moderne Browser, aber wir stellten fest, dass wir immer noch Probleme mit älteren Versionen von Micosoft Edge und Internet Explorer hatten.

Daher mussten wir dem sessionState-Knoten in der Datei web.config das Attribut cookieSameSite = "None" hinzufügen.

<sessionState cookieSameSite="None" />

Seien Sie jedoch vorsichtig mit dieser Konfigurationsänderung, da ältere .net Framework-Versionen diese nicht unterstützen und auf Ihrer Site eine Fehlerseite angezeigt wird.

Übrigens haben wir immer noch Probleme mit Browsern in IOS 12. Aber ich denke, es hängt mit diesem bestätigten Fehler zusammen

UPDATE 2 : In der Antwort von zemien finden Sie mögliche Lösungen für das IOS-Problem

UPDATE 3 : Indem wir unsere Ergebnisse mit den Vorschlägen in Zemiens Antwort kombinieren, haben wir die folgenden Umschreiberegeln entwickelt. Wir haben diese Konfiguration in der Produktion verwendet. Aber Vorsicht: Es markiert alle Cookies mit dem Attribut "SameSite: None" für kompatible Browser und schließt das SameSite-Attribut, falls vorhanden, für inkompatible Browser aus. Es mag kompliziert erscheinen, aber ich habe versucht, es über Kommentarzeilen zu erklären.

Dies ist die endgültige Konfiguration, die wir in der Produktion verwenden:

<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>
E. Özgür
quelle
Danke @ EÖzgür. Dieses Problem ist auf KB4533097 ( support.microsoft.com/en-us/help/4533097/kb4533097 ) zurückzuführen, insbesondere auf KB4533011 (.net 4.7 und niedriger) und KB4533004 (.net 4.8), die am 10. Dezember veröffentlicht wurden.
S. Pineau
Ich habe das gleiche Problem, aber manchmal gibt asp.net mvc dem Kunden ASP.NET_SessionId-Cookies mit LAX, manchmal mit NONE. Ich bin mir nicht sicher, warum es passiert. Ich meine, es sollte die ganze Zeit LAX sein, aber wenn ich mich vor Ort anmelde, kann ich KEINE bekommen.
Herzog
Oh Mann! Ich bin seit zwei Tagen verrückt nach diesem Thema. Schließlich rettete Ihre Antwort meinen Tag und meine Frustration. Vielen Dank.
Hemanth
1
Wir hatten dieses Problem auf Server 2016, nachdem wir Dezember-Updates angewendet hatten. (KB4530689). Vielen Dank, dass Sie die Lösung gefunden haben!
user0474975
Gilt das nur für den Dotnet-Kern? In meiner Framework-Anwendung zeige ich diese Optionen als ungültige Werte an, die festgelegt werden sollen.
IronSean
3

Ich habe mehrere SO-Antworten geändert, um diese URL-Neufassung zu erhalten, die SameSite=NoneSitzungscookies hinzufügt , und sie für die meisten inkompatiblen Browser SameSite=Noneaus allen Cookies zu entfernen . Ziel dieser Neufassung ist es, das "Legacy" -Verhalten vor Chrome 80 beizubehalten.

Vollständiger Artikel in meinem Coder Frontline-Blog :

<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>

Dies sollte für die meisten ASP .Net- und ASP .Net Core-Anwendungen funktionieren, obwohl neuere Frameworks über geeignete Code- und Konfigurationsoptionen verfügen, mit denen Sie dieses Verhalten steuern können. Ich würde empfehlen, alle verfügbaren Optionen zu prüfen, bevor Sie mein oben beschriebenes Umschreiben verwenden.

zemien
quelle