我们知道了。
不知何故,“ ASP.NET_SessionId” cookie的“ SameSite”属性默认为“ Lax”,这导致会话cookie不被添加到付款网关的javascript代码发出的请求中。
我们将以下规则添加到web.config文件中,以覆盖此值并将其设置为“ None”。
<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中遇到浏览器问题。但是我认为这与已确认的错误有关
更新2:请参阅zemien的答案以获取有关IOS问题的可能解决方法
更新3:通过将我们的发现与zemien答案中的建议相结合,我们提出了以下重写规则。我们一直在生产中使用此配置。但要注意:对于兼容的浏览器,它会将所有cookie标记为“ SameSite:None”,对于不兼容的浏览器,将排除SameSite属性(如果存在)。这似乎很复杂,但我尝试通过注释行进行解释。
这是我们在生产中使用的FINAL配置:
<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>