Trình duyệt sẽ không đặt cookie ASP.NET_SessionId theo yêu cầu bài đăng của cổng thanh toán đến trang web của chúng tôi


12

Chúng tôi đang gặp một vấn đề kỳ lạ với quy trình thanh toán của ứng dụng web của mình dẫn đến mất dữ liệu phiên.

Trong quá trình này, sau khi người dùng trang thanh toán của chúng tôi được chuyển hướng đến trang của nhà cung cấp thanh toán và được chuyển hướng trở lại trang web của chúng tôi (đến một url chúng tôi chỉ định) ngay khi họ hoàn thành. Chuyển hướng cuối cùng này được thực hiện bằng đánh giá của trình duyệt về mã html của nhà cung cấp dịch vụ thanh toán, về cơ bản bao gồm một biểu mẫu đăng lên trang web của chúng tôi và một vài dòng mã javascript đăng tải khi tải trang. Tại thời điểm này, trình duyệt thực hiện yêu cầu bài đăng nhưng không đặt cookie "ASP.NET_SessionId" có trong các yêu cầu trước đó được thực hiện cho cùng một tên miền (tên miền của ứng dụng của chúng tôi). Điều kỳ lạ hơn là nó đặt một cookie khác mà chúng tôi sử dụng có tên là "AcceptCookie". Nó chỉ đơn giản là chọn bỏ cookie "ASP.NET_SessionId".

Để minh họa tình huống tôi chụp một số ảnh chụp màn hình. (Trong các ảnh chụp màn hình này, hình chữ nhật màu cam và màu xanh lá cây chứa chính xác cùng một giá trị.)

  1. Đây là yêu cầu được thực hiện (đối với ứng dụng của chúng tôi) khi người dùng nhấn nút "Thanh toán". Sau khi yêu cầu này, người dùng được chuyển hướng đến trang của nhà cung cấp thanh toán.

yêu cầu trả phòng

  1. Đây là trang cuối cùng được cung cấp bởi nhà cung cấp thanh toán sau khi người dùng được thực hiện ở đó. Như bạn có thể thấy nó chỉ là một hình thức đơn giản được tự động đăng lên tên miền của chúng tôi khi tải trang.

phản hồi cuối cùng của nhà cung cấp thanh toán

  1. Nhưng yêu cầu bài đăng này không bao gồm cookie "ASP.NET_SessionId" dẫn đến việc có được id phiên mới và mất dữ liệu phiên trước đó. Và một lần nữa, chỉ thiếu "ASP.NET_SessionId", không phải cái khác có tên "AcceptCookie".

yêu cầu bài đăng đưa người dùng trở lại trang web của chúng tôi (được thực hiện bằng javascript ở bước trước)

Cuối cùng, chúng tôi đã tìm ra rằng trên các phiên bản cũ hơn của trình duyệt, vấn đề này không xảy ra. Trên Firefox 52, nó hoạt động như một bùa mê nhưng trên Firefox 71, vấn đề trên xảy ra.

Có ý kiến ​​gì không?

Lưu ý: Đây là một ứng dụng ASP.NET MVC có targetFramework = "4.5.2"

Chúc một ngày tốt lành.

Câu trả lời:


16

Chúng tôi đã tìm ra nó.

Bằng cách nào đó, thuộc tính "SameSite" của cookie "ASP.NET_SessionId" mặc định là "Lax" và điều này khiến cookie phiên không được thêm vào yêu cầu được thực hiện bởi mã javascript của cổng thanh toán.

Chúng tôi đã thêm quy tắc sau vào tệp web.config để ghi đè giá trị này và đặt thành "Không".

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

CẬP NHẬT 1 : Chỉ cần thêm cấu hình ở trên đã giải quyết vấn đề cho các trình duyệt hiện đại nhưng chúng tôi nhận ra rằng chúng tôi vẫn gặp sự cố với các phiên bản cũ hơn của Micosoft Edge và Internet Explorer.

Vì vậy, chúng tôi cần thêm thuộc tính cookieSameSite = "Không" vào nút sessionState trong tệp web.config.

<sessionState cookieSameSite="None" />

Tuy nhiên, hãy cẩn thận với thay đổi cấu hình này, vì các phiên bản khung .net cũ hơn không hỗ trợ nó và khiến trang web của bạn hiển thị trang lỗi.

Tuy nhiên, chúng tôi vẫn gặp sự cố với trình duyệt trong iOS 12. Nhưng tôi nghĩ nó liên quan đến lỗi đã được xác nhận này

CẬP NHẬT 2 : xem câu trả lời của zemien để biết cách khắc phục có thể về sự cố iOS

CẬP NHẬT 3 : Bằng cách kết hợp các phát hiện của chúng tôi với các đề xuất trong câu trả lời của zemien, chúng tôi đã đưa ra các quy tắc viết lại sau đây. Chúng tôi đã sử dụng cấu hình này trong sản xuất. Nhưng hãy cẩn thận: nó đánh dấu tất cả các cookie có thuộc tính "SameSite: none" cho các trình duyệt tương thích và loại trừ thuộc tính SameSite, nếu tồn tại, cho các trình duyệt không tương thích. Nó có vẻ phức tạp nhưng tôi đã cố gắng giải thích thông qua các dòng bình luận.

Đây là cấu hình FINAL mà chúng tôi sử dụng trong sản xuất:

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

Cảm ơn @ EÖzgür. Vấn đề này xuất phát từ KB4533097 ( support.microsoft.com/en-us/help/4533097/kb4533097 ) trên cụ thể nhất là KB4533011 (.net 4.7 trở xuống) và KB4533004 (.net 4.8) được phát hành vào ngày 10 tháng 12
S. Pineau

Tôi có cùng một vấn đề, nhưng đôi khi asp.net mvc cung cấp cho khách hàng cookie ASP.NET_SessionId với LAX đôi khi với NONE. Tôi không chắc tại sao nó xảy ra. Ý tôi là nó phải là LAX mọi lúc, nhưng khi tôi đăng nhập vào trang web tôi có thể nhận được KHÔNG.
Công tước

Trời ơi! Tôi đã phát điên về vấn đề này trong hai ngày. Cuối cùng câu trả lời của bạn đã cứu ngày và sự thất vọng của tôi. Cảm ơn.
Hemanth

1
Chúng tôi đã gặp sự cố này trên Server 2016 sau khi áp dụng các bản cập nhật tháng 12. (KB4530689). Rất cám ơn đã tìm ra giải pháp!
dùng0474975

Đây có phải chỉ dành cho lõi dotnet? Trong ứng dụng Khung của tôi, tôi đang hiển thị các tùy chọn đó là các giá trị không hợp lệ để đặt.
IronSean

3

Tôi đã sửa đổi một số câu trả lời SO để đưa ra cách viết lại URL này thêm SameSite=Nonevào cookie phiên và cũng xóa SameSite=Nonekhỏi tất cả các cookie cho hầu hết các trình duyệt không tương thích. Mục đích của việc viết lại này là để duy trì hành vi "di sản" trước Chrome 80.

Viết đầy đủ trong blog Coder Frontline của tôi :

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

Điều này sẽ hoạt động đối với hầu hết các ứng dụng ASP .Net và ASP .Net Core, mặc dù các Framework mới hơn có các tùy chọn cấu hình và mã phù hợp để cho phép bạn kiểm soát hành vi này. Tôi sẽ khuyên bạn nên nghiên cứu tất cả các tùy chọn có sẵn cho bạn trước khi sử dụng viết lại của tôi ở trên.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.