Browser tidak akan menetapkan cookie ASP.NET_SessionId pada permintaan posting gateway pembayaran ke situs kami


12

Kami mengalami masalah aneh dengan proses pembayaran aplikasi web kami yang mengakibatkan hilangnya data sesi.

Dalam proses ini, setelah pengguna halaman check-out kami dialihkan ke halaman penyedia pembayaran dan dialihkan kembali ke situs kami (ke url yang kami tentukan) segera setelah ia selesai di sana. Pengalihan terakhir ini dilakukan dengan evaluasi browser terhadap kode html penyedia pembayaran yang pada dasarnya terdiri dari formulir yang memposting ke situs kami dan beberapa baris kode javascript yang mem-posting formulir itu pada pemuatan halaman. Pada titik ini browser membuat permintaan posting tetapi tidak menetapkan cookie "ASP.NET_SessionId" yang ada dalam permintaan sebelumnya yang dibuat ke domain yang sama persis (domain aplikasi kami). Yang lebih aneh adalah ia membuat cookie lain yang kami gunakan bernama "AcceptCookie". Itu hanya memilih untuk menjatuhkan cookie "ASP.NET_SessionId".

Untuk mengilustrasikan situasi saya mengambil beberapa screenshot. (Dalam screenshot ini, persegi panjang oranye dan hijau mengandung nilai yang persis sama.)

  1. Ini adalah permintaan yang diajukan (ke aplikasi kami) ketika pengguna menekan tombol "Check Out". Setelah permintaan ini, pengguna diarahkan ke halaman penyedia pembayaran.

permintaan check-out

  1. Ini adalah halaman terakhir yang dilayani oleh penyedia pembayaran setelah pengguna selesai di sana. Seperti yang Anda lihat, itu hanya bentuk sederhana yang secara otomatis diposting ke domain kami saat memuat halaman.

Tanggapan akhir penyedia pembayaran

  1. Tetapi permintaan pos ini tidak termasuk cookie "ASP.NET_SessionId" yang berakibat memperoleh id sesi baru dan hilangnya data sesi sebelumnya. Dan lagi, hanya "ASP.NET_SessionId" yang hilang, bukan yang lain bernama "AcceptCookie".

memposting permintaan yang membawa pengguna kembali ke situs kami (dibuat dengan javascript pada langkah sebelumnya)

Akhirnya kami menemukan bahwa pada versi browser yang lebih lama masalah ini tidak terjadi. Pada Firefox 52 berfungsi seperti pesona tetapi pada Firefox 71 masalah di atas terjadi.

Ada ide?

Catatan: Ini adalah aplikasi ASP.NET MVC dengan targetFramework = "4.5.2"

Semoga harimu menyenangkan.

Jawaban:


16

Kami menemukan jawabannya.

Entah bagaimana "ASP.NET_SessionId" cookie "SameSite" atribut default ke "Lax" dan ini menyebabkan cookie sesi tidak ditambahkan ke permintaan yang dibuat oleh kode javascript gateway pembayaran.

Kami menambahkan aturan berikut ke file web.config untuk mengganti nilai ini dan mengaturnya ke "Tidak Ada".

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

PEMBARUAN 1 : Hanya menambahkan konfigurasi di atas memecahkan masalah untuk peramban modern tetapi kami menyadari bahwa kami masih mengalami masalah dengan versi lama Micosoft Edge dan Internet Explorer.

Jadi kami perlu menambahkan atribut cookieSameSite = "None" ke node sessionState di file web.config.

<sessionState cookieSameSite="None" />

Hati-hati dengan perubahan konfigurasi ini, karena versi .net framework yang lebih lama tidak mendukungnya dan menyebabkan situs Anda menampilkan halaman kesalahan.

Omong-omong, kami masih mengalami masalah dengan browser di iOS 12. Tapi saya pikir ini terkait dengan bug yang dikonfirmasi ini

UPDATE 2 : lihat jawaban zemien untuk kemungkinan perbaikan tentang masalah IOS

UPDATE 3 : Dengan menggabungkan temuan kami dengan saran dalam jawaban zemien, kami telah membuat aturan penulisan ulang berikut. Kami telah menggunakan konfigurasi ini dalam produksi. Namun berhati-hatilah: ini menandai semua cookie dengan atribut "SameSite: None" untuk browser yang kompatibel dan mengecualikan atribut SameSite, jika ada, untuk browser yang tidak kompatibel. Ini mungkin terlihat rumit tetapi saya mencoba menjelaskan melalui baris komentar.

Ini adalah konfigurasi FINAL yang kami gunakan dalam produksi:

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

Terima kasih @ EÖzgür. Masalah ini berasal dari KB4533097 ( support.microsoft.com/en-us/help/4533097/kb4533097 ) pada paling khusus KB4533011 (.net 4.7 dan lebih rendah) dan KB4533004 (.net 4.8) dirilis pada 10 Desember
S. Pineau

Saya memiliki masalah yang sama, tetapi kadang-kadang asp.net MVC memberikan cookie ASP.NET_SessionId pelanggan dengan LAX kadang-kadang dengan NONE. Saya tidak yakin mengapa itu terjadi. Maksud saya seharusnya LAX sepanjang waktu, tapi tetap saja ketika saya login di situs saya tidak bisa NONE.
Duke

Oh man! Saya sudah tergila-gila dengan masalah ini selama dua hari. Akhirnya jawaban Anda menyelamatkan hari dan frustrasi saya. Terima kasih.
Hemanth

1
Kami memiliki masalah ini terjadi pada Server 2016 setelah menerapkan pembaruan Desember. (KB4530689). Terima kasih banyak telah menemukan solusinya!
user0474975

Apakah ini hanya untuk inti dotnet? Dalam aplikasi Framework saya, saya menunjukkan opsi itu sebagai nilai yang tidak valid untuk ditetapkan.
IronSean

3

Saya memodifikasi beberapa jawaban SO untuk membuat penulisan ulang URL ini yang menambah SameSite=Nonecookie sesi, dan juga menghapus SameSite=Nonedari semua cookie untuk sebagian besar browser yang tidak kompatibel. Tujuan penulisan ulang ini adalah untuk menjaga perilaku "warisan" sebelum Chrome 80.

Tulisan lengkap di blog Coder Frontline saya :

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

Ini harus berfungsi untuk sebagian besar aplikasi ASP .Net dan ASP .Net Core, meskipun Kerangka yang lebih baru memiliki opsi kode dan konfigurasi yang tepat untuk memungkinkan Anda mengontrol perilaku ini. Saya akan merekomendasikan meneliti semua opsi yang tersedia untuk Anda sebelum menggunakan penulisan ulang saya di atas.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.