Tarayıcı, ödeme ağ geçidinin sitemize gönderdiği istek üzerine ASP.NET_SessionId çerezini ayarlamıyor


12

Web uygulamamızın ödeme sürecinde, oturum verilerinin kaybolmasına neden olan garip bir sorun yaşıyoruz.

Bu süreçte, çıkış sayfamızdan sonra kullanıcı ödeme sağlayıcısının sayfasına yönlendirilir ve işini bitirir bitirmez sitemize (belirttiğimiz bir url'ye) yönlendirilir. Bu son yönlendirme, tarayıcının ödeme sağlayıcısının html kodunu temelde sitemize gönderen bir formdan ve sayfa yüklemesinde oluşan birkaç javascript kod satırından oluşan değerlendirmesi ile yapılır. Bu noktada tarayıcı gönderi isteğini yapar ancak aynı etki alanına (uygulamamızın etki alanı) yapılan önceki isteklerde bulunan "ASP.NET_SessionId" çerezi ayarlamaz. Daha garip olan, "AcceptCookie" adlı başka bir çerez ayarlaması. Sadece "ASP.NET_SessionId" çerezini bırakmayı seçer.

Durumu göstermek için bazı ekran görüntüleri aldım. (Bu ekran görüntülerinde turuncu ve yeşil dikdörtgenler tam olarak aynı değeri içerir.)

  1. Bu, "Check Out" düğmesine bastığında (uygulamamıza) yapılan istektir. Bu istekten sonra kullanıcı ödeme sağlayıcısının sayfasına yönlendirilir.

çıkış talebi

  1. Bu, kullanıcı orada yapıldıktan sonra ödeme sağlayıcısı tarafından sunulan son sayfadır. Gördüğünüz gibi, sayfa yüklemesinde alanımıza otomatik olarak gönderilen basit bir form.

ödeme sağlayıcısının nihai yanıtı

  1. Ancak bu gönderi isteği, yeni bir oturum kimliği ve önceki oturum verilerinin kaybedilmesi ile sonuçlanan "ASP.NET_SessionId" çerezi içermez. Ve yine, sadece "ASP.NET_SessionId" eksik, "AcceptCookie" adlı diğeri değil.

kullanıcıyı sitemize geri getiren posta isteği (önceki adımda javascript ile yapılmıştır)

Son olarak, tarayıcıların eski sürümlerinde bu sorunun oluşmadığını düşündük. Firefox 52'de bir cazibe gibi çalışır, ancak Firefox 71'de yukarıdaki sorun ortaya çıkar.

Herhangi bir fikir?

Not: targetFramework = "4.5.2" olan bir ASP.NET MVC uygulamasıdır

İyi günler.

Yanıtlar:


16

Biz çözdük.

Her nasılsa "ASP.NET_SessionId" çerezinin "SameSite" özniteliği varsayılan olarak "Lax" olur ve bu, oturum çerezinin ödeme ağ geçidinin javascript kodu tarafından yapılan isteğe eklenmemesine neden olur.

Bu değeri geçersiz kılmak ve "None" olarak ayarlamak için web.config dosyasına aşağıdaki kuralı ekledik.

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

GÜNCELLEME 1 : Sadece yukarıdaki yapılandırmayı eklemek modern tarayıcılar için sorunu çözdü, ancak Micosoft Edge ve Internet Explorer'ın eski sürümleriyle ilgili sorun yaşadığımızı fark ettik.

Bu yüzden web.config dosyasındaki sessionState düğümüne cookieSameSite = "None" özniteliğini eklememiz gerekiyordu.

<sessionState cookieSameSite="None" />

Eski .net framework sürümleri bunu desteklemediğinden ve sitenizin hata sayfası görüntülemesine neden olduğundan bu yapılandırma değişikliğine dikkat edin.

Bu arada hala IOS 12'de tarayıcılarla ilgili sorunlar yaşıyoruz. Ama bence bu doğrulanmış hata ile ilgili

GÜNCELLEME 2 : IOS sorunuyla ilgili olası düzeltme için zemien'in cevabına bakın

GÜNCELLEME 3 : Bulgularımızı zemien'in cevabındaki önerilerle birleştirerek aşağıdaki yeniden yazma kurallarını bulduk. Bu konfigürasyonu üretimde kullanıyoruz. Ancak dikkat: tüm çerezleri uyumlu tarayıcılar için "SameSite: None" özniteliğiyle işaretler ve uyumsuz tarayıcılar için SameSite özniteliğini hariç tutar. Karmaşık görünebilir ama yorum satırları üzerinden açıklamaya çalıştım.

Üretimde kullandığımız FINAL yapılandırması:

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

Teşekkürler @ EÖzgür. Bu sorun , özellikle 10 Aralık'ta yayımlanan KB4533011 (.net 4.7 ve daha düşük sürümler) üzerinde KB4533097 ( support.microsoft.com/en-us/help/4533097/kb4533097 ) ve 10 Aralık'ta yayımlanan KB4533004 (.net 4.8) kaynaklarından kaynaklanmaktadır.
S. Pineau

Aynı sorun var, ama bazen asp.net mvc bazen NONE ile LAX ile müşteri ASP.NET_SessionId çerezleri vermek. Neden olduđundan emin deđilim. Yani her zaman LAX olmalı, ama yine de sitede giriş yaptığımda HİÇBİRİ alabilirim.
Duke

Ah adamım! İki gündür bu konuda çıldırdım. Sonunda cevabım günümü ve hayal kırıklığımı kurtardı. Teşekkürler.
Hemanth

1
Aralık güncellemelerini uyguladıktan sonra Server 2016'da bu sorunla karşılaştık. (KB4530689). Çözümü bulduğunuz için çok teşekkürler!
user0474975

Bu sadece dotnet çekirdeği için mi? Çerçeve uygulamamda, seçeneklerinizi ayarlanacak geçersiz değerler olarak gösteriyorum.
IronSean

3

Ben ekleyen bu URL yeniden yazma ile gelip birkaç SO cevapları üzerine modifiye SameSite=Noneoturumu çerezlere ve ayrıca kaldırmak SameSite=Nonegelen tüm en uyumsuz tarayıcılar için kurabiye. Bu yeniden yazmanın amacı, Chrome 80 öncesi "eski" davranışı korumaktır.

Coder Frontline blogumda tam yazı :

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

Bu, çoğu ASP .Net ve ASP .Net Core uygulaması için çalışmalıdır, ancak yeni Frameworks bu davranışı denetlemenize olanak tanıyan uygun kod ve yapılandırma seçeneklerine sahiptir. Yukarıdaki yeniden yazımı kullanmadan önce kullanabileceğiniz tüm seçenekleri araştırmanızı tavsiye ederim.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.