ブラウザは、ペイメントゲートウェイのサイトへのポストリクエストでASP.NET_SessionId Cookieを設定しません


12

Webアプリケーションの支払いプロセスで奇妙な問題が発生し、セッションデータが失われています。

このプロセスでは、チェックアウトページのユーザーが支払いプロバイダーのページにリダイレクトされ、サイトにアクセスするとすぐに(指定されたURLに)サイトにリダイレクトされます。この最後のリダイレクトは、基本的に私たちのサイトに投稿するフォームと、ページの読み込み時にそのフォームを投稿する数行のJavaScriptコードで構成される支払いプロバイダーのHTMLコードのブラウザーの評価によって行われます。この時点で、ブラウザはPOST要求を行いますが、まったく同じドメイン(アプリケーションのドメイン)に対して行われた以前の要求に存在する「ASP.NET_SessionId」Cookieを設定しません。さらに奇妙なのは、「AcceptCookie」という名前の別のCookieを設定することです。「ASP.NET_SessionId」Cookieをドロップすることを選択するだけです。

状況を説明するために、いくつかのスクリーンショットを撮りました。(これらのスクリーンショットでは、オレンジと緑の長方形にまったく同じ値が含まれています。)

  1. これは、ユーザーが「チェックアウト」ボタンを押したときに(アプリケーションに対して)行われた要求です。このリクエストの後、ユーザーは支払いプロバイダーのページにリダイレクトされます。

チェックアウトリクエスト

  1. これは、ユーザーがそこで完了した後に支払いプロバイダーによって提供される最後のページです。ご覧のとおり、ページの読み込み時にドメインに自動的に投稿されるのは単純なフォームです。

支払いプロバイダーの最終応答

  1. ただし、この投稿リクエストには「ASP.NET_SessionId」Cookieが含まれていないため、新しいセッションIDが取得され、以前のセッションデータが失われます。ここでも、「ASP.NET_SessionId」だけが欠落しており、「AcceptCookie」という名前のものは欠落しています。

ユーザーをサイトに戻すリクエストをポストします(前のステップでJavaScriptで作成)

最後に、古いバージョンのブラウザではこの問題は発生しないことを突き止めました。Firefox 52では魅力的に機能しますが、Firefox 71では上記の問題が発生します。

何か案は?

注:これは、targetFramework = "4.5.2"を含むASP.NET MVCアプリケーションです。

ごきげんよう。

回答:


16

私たちはそれを理解しました。

どういうわけか「ASP.NET_SessionId」Cookieの「SameSite」属性はデフォルトで「Lax」になり、これにより、セッションCookieが支払いゲートウェイのJavaScriptコードによって行われたリクエストに追加されなくなります。

この値を上書きして「なし」に設定するために、web.configファイルに次のルールを追加しました。

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

アップデート1:上記の構成を追加するだけで最新のブラウザーの問題は解決しましたが、Micosoft EdgeとInternet Explorerの古いバージョンではまだ問題が発生していることがわかりました。

そのため、web.configファイルのsessionStateノードにcookieSameSite = "None"属性を追加する必要がありました。

<sessionState cookieSameSite="None" />

ただし、古い.netフレームワークバージョンではサポートされておらず、サイトにエラーページが表示されるため、この構成変更には注意してください。

ちなみに、IOS 12のブラウザーにはまだ問題がありますが、これはこの確認済みのバグに関連していると思います

UPDATE 2:IOSの問題について考えられる修正については、zemienの回答を参照してください

更新3:調査結果とzemienの回答の提案を組み合わせることにより、次の書き換えルールを作成しました。この構成は本番環境で使用しています。ただし、注意してください。互換性のあるブラウザーの場合は、すべてのCookieに「SameSite:None」属性が付けられ、互換性のないブラウザーの場合は、SameSite属性が存在する場合は除外されます。複雑に見えるかもしれませんが、コメント行で説明しようとしました。

これは、本番環境で使用する最終構成です。

<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に感謝します。この問題は、KB4533097(から来support.microsoft.com/en-us/help/4533097/kb4533097 12月10日にリリース最も具体的KB4533011(.NET 4.7と下位)とKB4533004(.NET 4.8)上)
S.ピノー

私も同じ問題を抱えていますが、asp.net mvcがLAXを使用してASP.NET_SessionId Cookieを顧客に提供することがあります。なぜそうなるのかよくわかりません。常にLAXである必要がありますが、サイトにログインしてもNONEを取得できます。
デューク

ちょっと、あなた!私はこの問題に2日間夢中しています。最後に、あなたの答えは私の日と欲求不満を救いました。ありがとう。
Hemanth

1
12月のアップデートを適用した後、Server 2016でこの問題が発生しました。(KB4530689)。解決策を見つけてくれてありがとう!
user0474975

これはdotnetコア専用ですか?私のフレームワークアプリケーションでは、これらのオプションを無効な値として表示しています。
IronSean

3

私はいくつかのSOの回答を変更してSameSite=None、セッションCookieに追加するこのURL書き換えを考え出し、ほとんどの互換性のないブラウザーのすべての Cookie SameSite=Noneから削除しました。この書き換えの目的は、Chrome 80より前の「レガシー」動作を維持することです。

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>

これはほとんどのASP .NetおよびASP .Net Coreアプリケーションで機能しますが、新しいフレームワークには適切なコードと構成オプションがあり、この動作を制御できます。上記の私の書き換えを使用する前に、利用可能なすべてのオプションを調査することをお勧めします。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.