Add SameSitePolicy to CookiePolicyMiddleware
This commit is contained in:
parent
2a4a7dd26a
commit
769da5fd87
|
|
@ -33,7 +33,7 @@ namespace Microsoft.AspNetCore.Internal
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The default maximum size of characters in a cookie to send back to the client.
|
/// The default maximum size of characters in a cookie to send back to the client.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const int DefaultChunkSize = 4070;
|
public const int DefaultChunkSize = 4050;
|
||||||
|
|
||||||
private const string ChunkKeySuffix = "C";
|
private const string ChunkKeySuffix = "C";
|
||||||
private const string ChunkCountPrefix = "chunks-";
|
private const string ChunkCountPrefix = "chunks-";
|
||||||
|
|
@ -42,7 +42,7 @@ namespace Microsoft.AspNetCore.Internal
|
||||||
{
|
{
|
||||||
// Lowest common denominator. Safari has the lowest known limit (4093), and we leave little extra just in case.
|
// Lowest common denominator. Safari has the lowest known limit (4093), and we leave little extra just in case.
|
||||||
// See http://browsercookielimits.x64.me/.
|
// See http://browsercookielimits.x64.me/.
|
||||||
// Leave at least 20 in case CookiePolicy tries to add 'secure' and/or 'httponly'.
|
// Leave at least 40 in case CookiePolicy tries to add 'secure', 'samesite=strict' and/or 'httponly'.
|
||||||
ChunkSize = DefaultChunkSize;
|
ChunkSize = DefaultChunkSize;
|
||||||
ThrowForPartialCookies = true;
|
ThrowForPartialCookies = true;
|
||||||
}
|
}
|
||||||
|
|
@ -166,6 +166,7 @@ namespace Microsoft.AspNetCore.Internal
|
||||||
{
|
{
|
||||||
Domain = options.Domain,
|
Domain = options.Domain,
|
||||||
Expires = options.Expires,
|
Expires = options.Expires,
|
||||||
|
SameSite = (Net.Http.Headers.SameSiteMode)options.SameSite,
|
||||||
HttpOnly = options.HttpOnly,
|
HttpOnly = options.HttpOnly,
|
||||||
Path = options.Path,
|
Path = options.Path,
|
||||||
Secure = options.Secure,
|
Secure = options.Secure,
|
||||||
|
|
@ -284,6 +285,7 @@ namespace Microsoft.AspNetCore.Internal
|
||||||
{
|
{
|
||||||
Path = options.Path,
|
Path = options.Path,
|
||||||
Domain = options.Domain,
|
Domain = options.Domain,
|
||||||
|
SameSite = options.SameSite,
|
||||||
Expires = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc),
|
Expires = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -297,6 +299,7 @@ namespace Microsoft.AspNetCore.Internal
|
||||||
{
|
{
|
||||||
Path = options.Path,
|
Path = options.Path,
|
||||||
Domain = options.Domain,
|
Domain = options.Domain,
|
||||||
|
SameSite = options.SameSite,
|
||||||
Expires = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc),
|
Expires = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -179,6 +179,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
||||||
var cookieOptions = new CookieOptions
|
var cookieOptions = new CookieOptions
|
||||||
{
|
{
|
||||||
Domain = Options.CookieDomain,
|
Domain = Options.CookieDomain,
|
||||||
|
SameSite = Options.CookieSameSite,
|
||||||
HttpOnly = Options.CookieHttpOnly,
|
HttpOnly = Options.CookieHttpOnly,
|
||||||
Path = Options.CookiePath ?? (OriginalPathBase.HasValue ? OriginalPathBase.ToString() : "/"),
|
Path = Options.CookiePath ?? (OriginalPathBase.HasValue ? OriginalPathBase.ToString() : "/"),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
using System;
|
using System;
|
||||||
using Microsoft.AspNetCore.DataProtection;
|
using Microsoft.AspNetCore.DataProtection;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Authentication.Cookies
|
namespace Microsoft.AspNetCore.Authentication.Cookies
|
||||||
{
|
{
|
||||||
|
|
@ -23,6 +22,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
||||||
ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter;
|
ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter;
|
||||||
ExpireTimeSpan = TimeSpan.FromDays(14);
|
ExpireTimeSpan = TimeSpan.FromDays(14);
|
||||||
SlidingExpiration = true;
|
SlidingExpiration = true;
|
||||||
|
CookieSameSite = SameSiteMode.Strict;
|
||||||
CookieHttpOnly = true;
|
CookieHttpOnly = true;
|
||||||
CookieSecure = CookieSecurePolicy.SameAsRequest;
|
CookieSecure = CookieSecurePolicy.SameAsRequest;
|
||||||
Events = new CookieAuthenticationEvents();
|
Events = new CookieAuthenticationEvents();
|
||||||
|
|
@ -57,6 +57,12 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string CookiePath { get; set; }
|
public string CookiePath { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines if the browser should allow the cookie to be attached to same-site or cross-site requests. The
|
||||||
|
/// default is Strict, which means the cookie is only allowed to be attached to same-site requests.
|
||||||
|
/// </summary>
|
||||||
|
public SameSiteMode CookieSameSite { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if the browser should allow the cookie to be accessed by client-side javascript. The
|
/// Determines if the browser should allow the cookie to be accessed by client-side javascript. The
|
||||||
/// default is true, which means the cookie will only be passed to http requests and is not made available
|
/// default is true, which means the cookie will only be passed to http requests and is not made available
|
||||||
|
|
|
||||||
|
|
@ -899,6 +899,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
||||||
new CookieOptions
|
new CookieOptions
|
||||||
{
|
{
|
||||||
HttpOnly = true,
|
HttpOnly = true,
|
||||||
|
SameSite = Http.SameSiteMode.Lax,
|
||||||
Secure = Request.IsHttps,
|
Secure = Request.IsHttps,
|
||||||
Expires = Clock.UtcNow.Add(Options.ProtocolValidator.NonceLifetime)
|
Expires = Clock.UtcNow.Add(Options.ProtocolValidator.NonceLifetime)
|
||||||
});
|
});
|
||||||
|
|
@ -930,6 +931,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
||||||
var cookieOptions = new CookieOptions
|
var cookieOptions = new CookieOptions
|
||||||
{
|
{
|
||||||
HttpOnly = true,
|
HttpOnly = true,
|
||||||
|
SameSite = Http.SameSiteMode.Lax,
|
||||||
Secure = Request.IsHttps
|
Secure = Request.IsHttps
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,7 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
||||||
var cookieOptions = new CookieOptions
|
var cookieOptions = new CookieOptions
|
||||||
{
|
{
|
||||||
HttpOnly = true,
|
HttpOnly = true,
|
||||||
|
SameSite = SameSiteMode.Lax,
|
||||||
Secure = Request.IsHttps
|
Secure = Request.IsHttps
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -160,6 +161,7 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
||||||
var cookieOptions = new CookieOptions
|
var cookieOptions = new CookieOptions
|
||||||
{
|
{
|
||||||
HttpOnly = true,
|
HttpOnly = true,
|
||||||
|
SameSite = SameSiteMode.Lax,
|
||||||
Secure = Request.IsHttps,
|
Secure = Request.IsHttps,
|
||||||
Expires = Clock.UtcNow.Add(Options.RemoteAuthenticationTimeout),
|
Expires = Clock.UtcNow.Add(Options.RemoteAuthenticationTimeout),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -203,6 +203,7 @@ namespace Microsoft.AspNetCore.Authentication
|
||||||
var cookieOptions = new CookieOptions
|
var cookieOptions = new CookieOptions
|
||||||
{
|
{
|
||||||
HttpOnly = true,
|
HttpOnly = true,
|
||||||
|
SameSite = SameSiteMode.Lax,
|
||||||
Secure = Request.IsHttps,
|
Secure = Request.IsHttps,
|
||||||
Expires = Clock.UtcNow.Add(Options.RemoteAuthenticationTimeout),
|
Expires = Clock.UtcNow.Add(Options.RemoteAuthenticationTimeout),
|
||||||
};
|
};
|
||||||
|
|
@ -242,6 +243,7 @@ namespace Microsoft.AspNetCore.Authentication
|
||||||
var cookieOptions = new CookieOptions
|
var cookieOptions = new CookieOptions
|
||||||
{
|
{
|
||||||
HttpOnly = true,
|
HttpOnly = true,
|
||||||
|
SameSite = SameSiteMode.Lax,
|
||||||
Secure = Request.IsHttps
|
Secure = Request.IsHttps
|
||||||
};
|
};
|
||||||
Response.Cookies.Delete(cookieName, cookieOptions);
|
Response.Cookies.Delete(cookieName, cookieOptions);
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ namespace Microsoft.AspNetCore.CookiePolicy
|
||||||
|
|
||||||
private bool PolicyRequiresCookieOptions()
|
private bool PolicyRequiresCookieOptions()
|
||||||
{
|
{
|
||||||
return Policy.HttpOnly != HttpOnlyPolicy.None || Policy.Secure != CookieSecurePolicy.None;
|
return Policy.MinimumSameSitePolicy != SameSiteMode.None || Policy.HttpOnly != HttpOnlyPolicy.None || Policy.Secure != CookieSecurePolicy.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Append(string key, string value)
|
public void Append(string key, string value)
|
||||||
|
|
@ -151,6 +151,22 @@ namespace Microsoft.AspNetCore.CookiePolicy
|
||||||
default:
|
default:
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
}
|
}
|
||||||
|
switch (Policy.MinimumSameSitePolicy)
|
||||||
|
{
|
||||||
|
case SameSiteMode.None:
|
||||||
|
break;
|
||||||
|
case SameSiteMode.Lax:
|
||||||
|
if (options.SameSite == SameSiteMode.None)
|
||||||
|
{
|
||||||
|
options.SameSite = SameSiteMode.Lax;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SameSiteMode.Strict:
|
||||||
|
options.SameSite = SameSiteMode.Strict;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new InvalidOperationException($"Unrecognized {nameof(SameSiteMode)} value {Policy.MinimumSameSitePolicy.ToString()}");
|
||||||
|
}
|
||||||
switch (Policy.HttpOnly)
|
switch (Policy.HttpOnly)
|
||||||
{
|
{
|
||||||
case HttpOnlyPolicy.Always:
|
case HttpOnlyPolicy.Always:
|
||||||
|
|
@ -159,7 +175,7 @@ namespace Microsoft.AspNetCore.CookiePolicy
|
||||||
case HttpOnlyPolicy.None:
|
case HttpOnlyPolicy.None:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException($"Unrecognized {nameof(HttpOnlyPolicy)} value {Policy.HttpOnly.ToString()}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,11 @@ namespace Microsoft.AspNetCore.Builder
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class CookiePolicyOptions
|
public class CookiePolicyOptions
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Affects the cookie's same site attribute.
|
||||||
|
/// </summary>
|
||||||
|
public SameSiteMode MinimumSameSitePolicy { get; set; } = SameSiteMode.Strict;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Affects whether cookies must be HttpOnly.
|
/// Affects whether cookies must be HttpOnly.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -136,6 +136,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
||||||
Assert.StartsWith("TestCookie=", setCookie);
|
Assert.StartsWith("TestCookie=", setCookie);
|
||||||
Assert.Contains("; path=/", setCookie);
|
Assert.Contains("; path=/", setCookie);
|
||||||
Assert.Contains("; httponly", setCookie);
|
Assert.Contains("; httponly", setCookie);
|
||||||
|
Assert.Contains("; samesite=", setCookie);
|
||||||
Assert.DoesNotContain("; expires=", setCookie);
|
Assert.DoesNotContain("; expires=", setCookie);
|
||||||
Assert.DoesNotContain("; domain=", setCookie);
|
Assert.DoesNotContain("; domain=", setCookie);
|
||||||
Assert.DoesNotContain("; secure", setCookie);
|
Assert.DoesNotContain("; secure", setCookie);
|
||||||
|
|
@ -206,6 +207,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
||||||
o.CookiePath = "/foo";
|
o.CookiePath = "/foo";
|
||||||
o.CookieDomain = "another.com";
|
o.CookieDomain = "another.com";
|
||||||
o.CookieSecure = CookieSecurePolicy.Always;
|
o.CookieSecure = CookieSecurePolicy.Always;
|
||||||
|
o.CookieSameSite = SameSiteMode.None;
|
||||||
o.CookieHttpOnly = true;
|
o.CookieHttpOnly = true;
|
||||||
}, SignInAsAlice, baseAddress: new Uri("http://example.com/base"));
|
}, SignInAsAlice, baseAddress: new Uri("http://example.com/base"));
|
||||||
|
|
||||||
|
|
@ -217,12 +219,14 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
||||||
Assert.Contains(" path=/foo", setCookie1);
|
Assert.Contains(" path=/foo", setCookie1);
|
||||||
Assert.Contains(" domain=another.com", setCookie1);
|
Assert.Contains(" domain=another.com", setCookie1);
|
||||||
Assert.Contains(" secure", setCookie1);
|
Assert.Contains(" secure", setCookie1);
|
||||||
|
Assert.DoesNotContain(" samesite", setCookie1);
|
||||||
Assert.Contains(" httponly", setCookie1);
|
Assert.Contains(" httponly", setCookie1);
|
||||||
|
|
||||||
var server2 = CreateServer(o =>
|
var server2 = CreateServer(o =>
|
||||||
{
|
{
|
||||||
o.CookieName = "SecondCookie";
|
o.CookieName = "SecondCookie";
|
||||||
o.CookieSecure = CookieSecurePolicy.None;
|
o.CookieSecure = CookieSecurePolicy.None;
|
||||||
|
o.CookieSameSite = SameSiteMode.Strict;
|
||||||
o.CookieHttpOnly = false;
|
o.CookieHttpOnly = false;
|
||||||
}, SignInAsAlice, baseAddress: new Uri("http://example.com/base"));
|
}, SignInAsAlice, baseAddress: new Uri("http://example.com/base"));
|
||||||
|
|
||||||
|
|
@ -232,6 +236,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
||||||
|
|
||||||
Assert.Contains("SecondCookie=", setCookie2);
|
Assert.Contains("SecondCookie=", setCookie2);
|
||||||
Assert.Contains(" path=/base", setCookie2);
|
Assert.Contains(" path=/base", setCookie2);
|
||||||
|
Assert.Contains(" samesite=strict", setCookie2);
|
||||||
Assert.DoesNotContain(" domain=", setCookie2);
|
Assert.DoesNotContain(" domain=", setCookie2);
|
||||||
Assert.DoesNotContain(" secure", setCookie2);
|
Assert.DoesNotContain(" secure", setCookie2);
|
||||||
Assert.DoesNotContain(" httponly", setCookie2);
|
Assert.DoesNotContain(" httponly", setCookie2);
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ namespace Microsoft.AspNetCore.Internal
|
||||||
new ChunkingCookieManager() { ChunkSize = null }.AppendResponseCookie(context, "TestCookie", testString, new CookieOptions());
|
new ChunkingCookieManager() { ChunkSize = null }.AppendResponseCookie(context, "TestCookie", testString, new CookieOptions());
|
||||||
var values = context.Response.Headers["Set-Cookie"];
|
var values = context.Response.Headers["Set-Cookie"];
|
||||||
Assert.Equal(1, values.Count);
|
Assert.Equal(1, values.Count);
|
||||||
Assert.Equal("TestCookie=" + testString + "; path=/", values[0]);
|
Assert.Equal("TestCookie=" + testString + "; path=/; samesite=lax", values[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -27,20 +27,20 @@ namespace Microsoft.AspNetCore.Internal
|
||||||
HttpContext context = new DefaultHttpContext();
|
HttpContext context = new DefaultHttpContext();
|
||||||
|
|
||||||
string testString = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
string testString = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
new ChunkingCookieManager() { ChunkSize = 30 }.AppendResponseCookie(context, "TestCookie", testString, new CookieOptions());
|
new ChunkingCookieManager() { ChunkSize = 44 }.AppendResponseCookie(context, "TestCookie", testString, new CookieOptions());
|
||||||
var values = context.Response.Headers["Set-Cookie"];
|
var values = context.Response.Headers["Set-Cookie"];
|
||||||
Assert.Equal(9, values.Count);
|
Assert.Equal(9, values.Count);
|
||||||
Assert.Equal<string[]>(new[]
|
Assert.Equal<string[]>(new[]
|
||||||
{
|
{
|
||||||
"TestCookie=chunks-8; path=/",
|
"TestCookie=chunks-8; path=/; samesite=lax",
|
||||||
"TestCookieC1=abcdefgh; path=/",
|
"TestCookieC1=abcdefgh; path=/; samesite=lax",
|
||||||
"TestCookieC2=ijklmnop; path=/",
|
"TestCookieC2=ijklmnop; path=/; samesite=lax",
|
||||||
"TestCookieC3=qrstuvwx; path=/",
|
"TestCookieC3=qrstuvwx; path=/; samesite=lax",
|
||||||
"TestCookieC4=yz012345; path=/",
|
"TestCookieC4=yz012345; path=/; samesite=lax",
|
||||||
"TestCookieC5=6789ABCD; path=/",
|
"TestCookieC5=6789ABCD; path=/; samesite=lax",
|
||||||
"TestCookieC6=EFGHIJKL; path=/",
|
"TestCookieC6=EFGHIJKL; path=/; samesite=lax",
|
||||||
"TestCookieC7=MNOPQRST; path=/",
|
"TestCookieC7=MNOPQRST; path=/; samesite=lax",
|
||||||
"TestCookieC8=UVWXYZ; path=/",
|
"TestCookieC8=UVWXYZ; path=/; samesite=lax",
|
||||||
}, values);
|
}, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -116,14 +116,14 @@ namespace Microsoft.AspNetCore.Internal
|
||||||
Assert.Equal(8, cookies.Count);
|
Assert.Equal(8, cookies.Count);
|
||||||
Assert.Equal(new[]
|
Assert.Equal(new[]
|
||||||
{
|
{
|
||||||
"TestCookie=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/",
|
"TestCookie=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; samesite=lax",
|
||||||
"TestCookieC1=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/",
|
"TestCookieC1=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; samesite=lax",
|
||||||
"TestCookieC2=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/",
|
"TestCookieC2=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; samesite=lax",
|
||||||
"TestCookieC3=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/",
|
"TestCookieC3=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; samesite=lax",
|
||||||
"TestCookieC4=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/",
|
"TestCookieC4=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; samesite=lax",
|
||||||
"TestCookieC5=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/",
|
"TestCookieC5=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; samesite=lax",
|
||||||
"TestCookieC6=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/",
|
"TestCookieC6=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; samesite=lax",
|
||||||
"TestCookieC7=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/",
|
"TestCookieC7=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; samesite=lax",
|
||||||
}, cookies);
|
}, cookies);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,15 @@ namespace Microsoft.AspNetCore.CookiePolicy.Test
|
||||||
context.Response.Cookies.Append("D", "D", new CookieOptions { HttpOnly = true });
|
context.Response.Cookies.Append("D", "D", new CookieOptions { HttpOnly = true });
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
};
|
};
|
||||||
|
private RequestDelegate SameSiteCookieAppends = context =>
|
||||||
|
{
|
||||||
|
context.Response.Cookies.Append("A", "A");
|
||||||
|
context.Response.Cookies.Append("B", "B", new CookieOptions { SameSite = Http.SameSiteMode.None });
|
||||||
|
context.Response.Cookies.Append("C", "C", new CookieOptions());
|
||||||
|
context.Response.Cookies.Append("D", "D", new CookieOptions { SameSite = Http.SameSiteMode.Lax });
|
||||||
|
context.Response.Cookies.Append("E", "E", new CookieOptions { SameSite = Http.SameSiteMode.Strict });
|
||||||
|
return Task.FromResult(0);
|
||||||
|
};
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task SecureAlwaysSetsSecure()
|
public async Task SecureAlwaysSetsSecure()
|
||||||
|
|
@ -50,10 +59,10 @@ namespace Microsoft.AspNetCore.CookiePolicy.Test
|
||||||
transaction =>
|
transaction =>
|
||||||
{
|
{
|
||||||
Assert.NotNull(transaction.SetCookie);
|
Assert.NotNull(transaction.SetCookie);
|
||||||
Assert.Equal("A=A; path=/; secure", transaction.SetCookie[0]);
|
Assert.Equal("A=A; path=/; secure; samesite=strict", transaction.SetCookie[0]);
|
||||||
Assert.Equal("B=B; path=/; secure", transaction.SetCookie[1]);
|
Assert.Equal("B=B; path=/; secure; samesite=strict", transaction.SetCookie[1]);
|
||||||
Assert.Equal("C=C; path=/; secure", transaction.SetCookie[2]);
|
Assert.Equal("C=C; path=/; secure; samesite=strict", transaction.SetCookie[2]);
|
||||||
Assert.Equal("D=D; path=/; secure", transaction.SetCookie[3]);
|
Assert.Equal("D=D; path=/; secure; samesite=strict", transaction.SetCookie[3]);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -70,10 +79,10 @@ namespace Microsoft.AspNetCore.CookiePolicy.Test
|
||||||
transaction =>
|
transaction =>
|
||||||
{
|
{
|
||||||
Assert.NotNull(transaction.SetCookie);
|
Assert.NotNull(transaction.SetCookie);
|
||||||
Assert.Equal("A=A; path=/", transaction.SetCookie[0]);
|
Assert.Equal("A=A; path=/; samesite=strict", transaction.SetCookie[0]);
|
||||||
Assert.Equal("B=B; path=/", transaction.SetCookie[1]);
|
Assert.Equal("B=B; path=/; samesite=strict", transaction.SetCookie[1]);
|
||||||
Assert.Equal("C=C; path=/", transaction.SetCookie[2]);
|
Assert.Equal("C=C; path=/; samesite=strict", transaction.SetCookie[2]);
|
||||||
Assert.Equal("D=D; path=/; secure", transaction.SetCookie[3]);
|
Assert.Equal("D=D; path=/; secure; samesite=strict", transaction.SetCookie[3]);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -90,19 +99,19 @@ namespace Microsoft.AspNetCore.CookiePolicy.Test
|
||||||
transaction =>
|
transaction =>
|
||||||
{
|
{
|
||||||
Assert.NotNull(transaction.SetCookie);
|
Assert.NotNull(transaction.SetCookie);
|
||||||
Assert.Equal("A=A; path=/", transaction.SetCookie[0]);
|
Assert.Equal("A=A; path=/; samesite=strict", transaction.SetCookie[0]);
|
||||||
Assert.Equal("B=B; path=/", transaction.SetCookie[1]);
|
Assert.Equal("B=B; path=/; samesite=strict", transaction.SetCookie[1]);
|
||||||
Assert.Equal("C=C; path=/", transaction.SetCookie[2]);
|
Assert.Equal("C=C; path=/; samesite=strict", transaction.SetCookie[2]);
|
||||||
Assert.Equal("D=D; path=/", transaction.SetCookie[3]);
|
Assert.Equal("D=D; path=/; samesite=strict", transaction.SetCookie[3]);
|
||||||
}),
|
}),
|
||||||
new RequestTest("https://example.com/secureSame",
|
new RequestTest("https://example.com/secureSame",
|
||||||
transaction =>
|
transaction =>
|
||||||
{
|
{
|
||||||
Assert.NotNull(transaction.SetCookie);
|
Assert.NotNull(transaction.SetCookie);
|
||||||
Assert.Equal("A=A; path=/; secure", transaction.SetCookie[0]);
|
Assert.Equal("A=A; path=/; secure; samesite=strict", transaction.SetCookie[0]);
|
||||||
Assert.Equal("B=B; path=/; secure", transaction.SetCookie[1]);
|
Assert.Equal("B=B; path=/; secure; samesite=strict", transaction.SetCookie[1]);
|
||||||
Assert.Equal("C=C; path=/; secure", transaction.SetCookie[2]);
|
Assert.Equal("C=C; path=/; secure; samesite=strict", transaction.SetCookie[2]);
|
||||||
Assert.Equal("D=D; path=/; secure", transaction.SetCookie[3]);
|
Assert.Equal("D=D; path=/; secure; samesite=strict", transaction.SetCookie[3]);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -119,10 +128,10 @@ namespace Microsoft.AspNetCore.CookiePolicy.Test
|
||||||
transaction =>
|
transaction =>
|
||||||
{
|
{
|
||||||
Assert.NotNull(transaction.SetCookie);
|
Assert.NotNull(transaction.SetCookie);
|
||||||
Assert.Equal("A=A; path=/; httponly", transaction.SetCookie[0]);
|
Assert.Equal("A=A; path=/; samesite=strict; httponly", transaction.SetCookie[0]);
|
||||||
Assert.Equal("B=B; path=/; httponly", transaction.SetCookie[1]);
|
Assert.Equal("B=B; path=/; samesite=strict; httponly", transaction.SetCookie[1]);
|
||||||
Assert.Equal("C=C; path=/; httponly", transaction.SetCookie[2]);
|
Assert.Equal("C=C; path=/; samesite=strict; httponly", transaction.SetCookie[2]);
|
||||||
Assert.Equal("D=D; path=/; httponly", transaction.SetCookie[3]);
|
Assert.Equal("D=D; path=/; samesite=strict; httponly", transaction.SetCookie[3]);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -137,12 +146,75 @@ namespace Microsoft.AspNetCore.CookiePolicy.Test
|
||||||
HttpCookieAppends,
|
HttpCookieAppends,
|
||||||
new RequestTest("http://example.com/httpOnlyNone",
|
new RequestTest("http://example.com/httpOnlyNone",
|
||||||
transaction =>
|
transaction =>
|
||||||
|
{
|
||||||
|
Assert.NotNull(transaction.SetCookie);
|
||||||
|
Assert.Equal("A=A; path=/; samesite=strict", transaction.SetCookie[0]);
|
||||||
|
Assert.Equal("B=B; path=/; samesite=strict", transaction.SetCookie[1]);
|
||||||
|
Assert.Equal("C=C; path=/; samesite=strict", transaction.SetCookie[2]);
|
||||||
|
Assert.Equal("D=D; path=/; samesite=strict; httponly", transaction.SetCookie[3]);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task SameSiteStrictSetsItAlways()
|
||||||
|
{
|
||||||
|
await RunTest("/sameSiteStrict",
|
||||||
|
new CookiePolicyOptions
|
||||||
|
{
|
||||||
|
MinimumSameSitePolicy = Http.SameSiteMode.Strict
|
||||||
|
},
|
||||||
|
SameSiteCookieAppends,
|
||||||
|
new RequestTest("http://example.com/sameSiteStrict",
|
||||||
|
transaction =>
|
||||||
|
{
|
||||||
|
Assert.NotNull(transaction.SetCookie);
|
||||||
|
Assert.Equal("A=A; path=/; samesite=strict", transaction.SetCookie[0]);
|
||||||
|
Assert.Equal("B=B; path=/; samesite=strict", transaction.SetCookie[1]);
|
||||||
|
Assert.Equal("C=C; path=/; samesite=strict", transaction.SetCookie[2]);
|
||||||
|
Assert.Equal("D=D; path=/; samesite=strict", transaction.SetCookie[3]);
|
||||||
|
Assert.Equal("E=E; path=/; samesite=strict", transaction.SetCookie[4]);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task SameSiteLaxSetsItAlways()
|
||||||
|
{
|
||||||
|
await RunTest("/sameSiteLax",
|
||||||
|
new CookiePolicyOptions
|
||||||
|
{
|
||||||
|
MinimumSameSitePolicy = Http.SameSiteMode.Lax
|
||||||
|
},
|
||||||
|
SameSiteCookieAppends,
|
||||||
|
new RequestTest("http://example.com/sameSiteLax",
|
||||||
|
transaction =>
|
||||||
|
{
|
||||||
|
Assert.NotNull(transaction.SetCookie);
|
||||||
|
Assert.Equal("A=A; path=/; samesite=lax", transaction.SetCookie[0]);
|
||||||
|
Assert.Equal("B=B; path=/; samesite=lax", transaction.SetCookie[1]);
|
||||||
|
Assert.Equal("C=C; path=/; samesite=lax", transaction.SetCookie[2]);
|
||||||
|
Assert.Equal("D=D; path=/; samesite=lax", transaction.SetCookie[3]);
|
||||||
|
Assert.Equal("E=E; path=/; samesite=strict", transaction.SetCookie[4]);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task SameSiteNoneLeavesItAlone()
|
||||||
|
{
|
||||||
|
await RunTest("/sameSiteNone",
|
||||||
|
new CookiePolicyOptions
|
||||||
|
{
|
||||||
|
MinimumSameSitePolicy = Http.SameSiteMode.None
|
||||||
|
},
|
||||||
|
SameSiteCookieAppends,
|
||||||
|
new RequestTest("http://example.com/sameSiteNone",
|
||||||
|
transaction =>
|
||||||
{
|
{
|
||||||
Assert.NotNull(transaction.SetCookie);
|
Assert.NotNull(transaction.SetCookie);
|
||||||
Assert.Equal("A=A; path=/", transaction.SetCookie[0]);
|
Assert.Equal("A=A; path=/", transaction.SetCookie[0]);
|
||||||
Assert.Equal("B=B; path=/", transaction.SetCookie[1]);
|
Assert.Equal("B=B; path=/", transaction.SetCookie[1]);
|
||||||
Assert.Equal("C=C; path=/", transaction.SetCookie[2]);
|
Assert.Equal("C=C; path=/; samesite=lax", transaction.SetCookie[2]);
|
||||||
Assert.Equal("D=D; path=/; httponly", transaction.SetCookie[3]);
|
Assert.Equal("D=D; path=/; samesite=lax", transaction.SetCookie[3]);
|
||||||
|
Assert.Equal("E=E; path=/; samesite=strict", transaction.SetCookie[4]);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -170,10 +242,10 @@ namespace Microsoft.AspNetCore.CookiePolicy.Test
|
||||||
var transaction = await server.SendAsync("http://example.com/login");
|
var transaction = await server.SendAsync("http://example.com/login");
|
||||||
|
|
||||||
Assert.NotNull(transaction.SetCookie);
|
Assert.NotNull(transaction.SetCookie);
|
||||||
Assert.Equal("Hao=Hao; path=/", transaction.SetCookie[0]);
|
Assert.Equal("Hao=Hao; path=/; samesite=strict", transaction.SetCookie[0]);
|
||||||
Assert.Equal("Hao=Hao; path=/", transaction.SetCookie[1]);
|
Assert.Equal("Hao=Hao; path=/; samesite=strict", transaction.SetCookie[1]);
|
||||||
Assert.Equal("Hao=Hao; path=/", transaction.SetCookie[2]);
|
Assert.Equal("Hao=Hao; path=/; samesite=strict", transaction.SetCookie[2]);
|
||||||
Assert.Equal("Hao=Hao; path=/; secure", transaction.SetCookie[3]);
|
Assert.Equal("Hao=Hao; path=/; secure; samesite=strict", transaction.SetCookie[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -201,7 +273,7 @@ namespace Microsoft.AspNetCore.CookiePolicy.Test
|
||||||
|
|
||||||
Assert.NotNull(transaction.SetCookie);
|
Assert.NotNull(transaction.SetCookie);
|
||||||
Assert.Equal(1, transaction.SetCookie.Count);
|
Assert.Equal(1, transaction.SetCookie.Count);
|
||||||
Assert.Equal("A=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/", transaction.SetCookie[0]);
|
Assert.Equal("A=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; samesite=lax", transaction.SetCookie[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue