O navegador não define o cookie ASP.NET_SessionId na solicitação de postagem do gateway de pagamento em nosso site


12

Estamos com um problema estranho com o processo de pagamento de nosso aplicativo Web, que resulta na perda de dados da sessão.

Nesse processo, depois que o usuário da nossa página de check-out é redirecionado para a página do provedor de pagamento e redirecionado de volta para o nosso site (para um URL que especificamos) assim que ele é feito lá. Esse último redirecionamento é feito pela avaliação do navegador do código html do provedor de pagamento, que consiste basicamente em um formulário que é postado em nosso site e em algumas linhas de código javascript que postam esse formulário no carregamento da página. Nesse momento, o navegador faz a solicitação de postagem, mas não define o cookie "ASP.NET_SessionId", presente nas solicitações anteriores feitas exatamente no mesmo domínio (o domínio de nosso aplicativo). O mais estranho é que ele define outro cookie que usamos chamado "AcceptCookie". Simplesmente escolhe soltar o cookie "ASP.NET_SessionId".

Para ilustrar a situação, tirei algumas capturas de tela. (Nestas capturas de tela, os retângulos laranja e verde contêm exatamente o mesmo valor.)

  1. Esta é a solicitação que foi feita (para nosso aplicativo) quando o usuário pressiona o botão "Check Out". Após essa solicitação, o usuário é redirecionado para a página do provedor de pagamento.

pedido de check-out

  1. Esta é a página final que é exibida pelo provedor de pagamento depois que o usuário é feito lá. Como você pode ver, é apenas um formulário simples que é postado automaticamente em nosso domínio no carregamento da página.

resposta final do provedor de pagamento

  1. Mas essa solicitação de postagem não inclui o cookie "ASP.NET_SessionId", que resulta na aquisição de um novo ID de sessão e na perda de dados da sessão anterior. E novamente, apenas "ASP.NET_SessionId" está ausente, e não o outro chamado "AcceptCookie".

solicitação de postagem que traz o usuário de volta ao nosso site (feito com javascript na etapa anterior)

Finalmente, descobrimos que nas versões mais antigas dos navegadores esse problema não ocorre. No Firefox 52 funciona como um encanto, mas no Firefox 71 o problema acima acontece.

Alguma ideia?

Nota: É um aplicativo ASP.NET MVC com targetFramework = "4.5.2"

Tenha um bom dia.

Respostas:


16

Nós descobrimos isso.

De alguma forma, o atributo "SameSite" do cookie "ASP.NET_SessionId" é padronizado como "Lax" e isso faz com que o cookie da sessão não seja adicionado à solicitação feita pelo código javascript do gateway de pagamento.

Adicionamos a seguinte regra ao arquivo web.config para substituir esse valor e defini-lo como "Nenhum".

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

ATUALIZAÇÃO 1 : A adição da configuração acima resolveu o problema dos navegadores modernos, mas percebemos que ainda estávamos tendo problemas com as versões mais antigas do Micosoft Edge e do Internet Explorer.

Portanto, precisamos adicionar o atributo cookieSameSite = "None" ao nó sessionState no arquivo web.config.

<sessionState cookieSameSite="None" />

Porém, tenha cuidado com essa alteração na configuração, pois as versões mais antigas da estrutura .net não a suportam e fazem com que seu site exiba página de erro.

A propósito, ainda estamos tendo problemas com navegadores no IOS 12. Mas acho que está relacionado a esse bug confirmado

ATUALIZAÇÃO 2 : consulte a resposta do zemien para obter uma possível correção sobre o problema do IOS

ATUALIZAÇÃO 3 : Ao combinar nossas descobertas com as sugestões da resposta do zemien, criamos as seguintes regras de reescrita. Temos usado essa configuração na produção. Mas cuidado: marca todos os cookies com o atributo "SameSite: None" para navegadores compatíveis e exclui o atributo SameSite, se existir, para navegadores incompatíveis. Pode parecer complicado, mas tentei explicar por meio de linhas de comentário.

Esta é a configuração FINAL que usamos na produção:

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

Obrigado @ EÖzgür. Esse problema vem do KB4533097 ( support.microsoft.com/en-us/help/4533097/kb4533097 ) no KB4533011 (.net 4.7 e inferior) e KB4533004 (.net 4.8) lançado em 10 de dezembro
S. Pineau

Eu tenho o mesmo problema, mas às vezes o asp.net mvc fornece ao cliente cookies ASP.NET_SessionId com LAX, às vezes com NONE. Não sei por que isso acontece. Quero dizer, deve estar em LAX o tempo todo, mas ainda assim, quando eu entrar no site, não consigo NENHUM.
Duke

Oh cara! Estou louco por esse problema há dois dias. Finalmente sua resposta salvou meu dia e frustração. Obrigado.
Hemanth 25/01

11
Tivemos esse problema no Server 2016 após a aplicação das atualizações de dezembro. (KB4530689). Muito obrigado por encontrar a solução!
user0474975 28/01

Isso é apenas para o núcleo dotnet? No meu aplicativo Framework, estou mostrando essas opções como valores inválidos para definir.
IronSean 28/01

3

Eu modifiquei várias respostas do SO para criar essa reescrita de URL que adiciona SameSite=Noneaos cookies de sessão e também removi SameSite=Nonede todos os cookies da maioria dos navegadores incompatíveis. O objetivo dessa reescrita é preservar o comportamento "legado" anterior ao Chrome 80.

Artigo completo no meu blog 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>

Isso deve funcionar para a maioria dos aplicativos ASP .Net e ASP .Net Core, embora as Estruturas mais recentes possuam código e opções de configuração adequadas para permitir que você controle esse comportamento. Eu recomendaria pesquisar todas as opções disponíveis antes de usar minha reescrita acima.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.