How to set SameSite value to None in .net 4.5.2?

Viewed 7148

When redirected back to my site from the third party site user session becoming empty. I have checked Response.Cookies["ASP.NET_SessionId"]; sets new value after redirect. By default, ASP.NET_SessionId it sets as Lax. Any possible way to change SameSite value in Session_Start of .net framework 4.5.2 or possible anywhere?

4 Answers

Couple options to work around this constraint with older versions of the .net framework

HttpContext.Current.Response.Headers.Append("set-cookie", $"{key}={value}; path=/; SameSite=Strict; Secure");

Is one option for setting the headers manually with the SameSite defined. Above, key is the cookie name, value is the cookie value

Alternatively:

myCookie.Path = "/; SameSite=Strict; Secure";

I've tested these options, both appear to work

Values listed above are for examples only, you will need to supply the appropriate values [Lax|Strict|None|etc]. The Secure flag indicates that its transmitted over https only. Ymmv

The trick with

cookie.Path = strCookiePath + "; SameSite=None";

doesn't work anymore (Fx 4.5.2). I searched the whole day for a solution, because we can't upgrade the Fx-Version for the site in question.

We found the following solution for the situation, where the cookie exists in the request:

using System.Reflection;
...
HttpCookie cookie = HttpContext.Current.Request.Cookies[key];
cookie.Secure = false; // Set whatever properties you need

PropertyInfo pti = cookie.GetType().GetProperty("SameSite");
if ( null != pti )
{
    pti.SetValue( cookie, -1 );  // -1 => Lax, 0 => None
}

HttpContext.Current.Response.Cookies.Add( cookie );

I hope it might be useful for somebody. The point here is, that the cookie was set with FormsAuthentication.SetAuthCookie, which doesn't set a value for SameSite. The browser turns the missing property into the "Lax" value. If you want to reset the cookie, the default value read from the request is "None". If you send the cookie without changing the SameSite-Property, the browser won't update the cookie, because the SameSite-Property of the new cookie (None) is not the same as the original (Lax).

Therefore you must change the value somehow. But since the browser sends the property to the server, the property exists and can be changed using reflection.

Just add in web.config

<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; Secure=true" />
      <conditions>
      </conditions>
    </rule>
    <preConditions>
      <preCondition name="No SameSite">
        <add input="{RESPONSE_Set_Cookie}" pattern="." />
        <add input="{RESPONSE_Set_Cookie}" pattern="; SameSite=none; Secure=true" negate="true" />
      </preCondition>
    </preConditions>
  </outboundRules>
</rewrite>

You can set the cookieSameSite-attribute in the web.config file:

<system.web>
    <httpCookies sameSite="None"/>
    <sessionState cookieSameSite="None" />

If you're using forms authentication, you can do this for the auth-cookie in the web.config file, too:

<authentication mode="Forms">
  <forms cookieSameSite="None" />
</authentication>

e.g. in SSRS:

<authentication mode="Forms">
  <forms loginUrl="logon.aspx" name="sqlAuthCookie" timeout="3000" path="/" cookieSameSite="None">
  </forms>
</authentication>

If you're doing it for a System.Web.HttpCookie in code, you can abuse the cookie-path to set the same-site attribute:

authCookie.Path = "/; SameSite=None";

e.g.

string userName = "MY_USER";
bool createPersistentCookie = true;
string strCookiePath = "/"; 


System.Web.HttpCookie authCookie = System.Web.Security.FormsAuthentication.GetAuthCookie(userName, createPersistentCookie, strCookiePath);


// intranet urls most of the times should not contain a dot 
// so this means if(not intranet)
// if (current.Request.Url.Host.Contains("."))
// secure can only be set when protocol is https
if ("https".Equals(current.Request.Url.Scheme, System.StringComparison.InvariantCultureIgnoreCase)) 
{
    //authCookie.Path = "/; SameSite=Strict";
    authCookie.Path = strCookiePath + "; SameSite=None";
    authCookie.Secure = true;
} 

System.Web.HttpContext.Current.Response.Cookies.Add(authCookie);
Related