Работа с файлами cookie SameSite в ASP.NET Core
Автор: Рик Андерсон (Rick Anderson)
SameSite — это стандартный проект IETF, предназначенный для обеспечения некоторой защиты от атак на межсайтовые подделки (CSRF). Первоначально проект был составлен в 2016 году, проект стандарта был обновлен в 2019 году. Обновленный стандарт не совместим с предыдущим стандартом, что является наиболее заметным отличием:
- Файлы cookie без заголовка SameSite обрабатываются как
SameSite=Lax
по умолчанию. SameSite=None
необходимо использовать для разрешения использования между сайтами cookie .- Файлы cookie, которые утверждают
SameSite=None
, также должны быть помечены какSecure
. - Приложения, которые используются
<iframe>
, могут столкнуться с проблемами сsameSite=Lax
файлами cookie илиsameSite=Strict
файлами cookie, так как<iframe>
рассматриваются как сценарии между сайтами. - Значение
SameSite=None
не допускается стандартом 2016 года и приводит к тому, что некоторые реализации обрабатывают такие файлы cookie, какSameSite=Strict
. См. статью "Поддержка старых браузеров " в этом документе.
Этот SameSite=Lax
параметр подходит для большинства файлов cookie приложений. Некоторые формы проверки подлинности, такие как OpenID Connect (OIDC) и WS-Federation по умолчанию перенаправления на основе POST. Перенаправление на основе POST активирует защиту браузера SameSite, поэтому Для этих компонентов отключается Тот же сайт. Большинство имен входа OAuth не затрагиваются из-за различий в том, как потоки запросов.
Каждый компонент ASP.NET Core, который выдает файлы cookie, должен решить, подходит ли тот же сайт.
SameSite и Identity
ASP.NET Core Identity в значительной степени не влияет на файлы cookie SameSite, за исключением расширенных сценариев, таких как IFrames
или OpenIdConnect
интеграция.
При использовании Identity
не добавляйте cookie поставщиков и не вызывайте services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
их. Identity
Пример кода теста SameSite
Следующий пример можно скачать и проверить:
Пример | Документ |
---|---|
Страницы .NET Core Razor | пример ASP.NET Core 3.1 Razor Pages SameSite cookie |
Поддержка .NET Core для того же атрибута.
.NET Core поддерживает стандартный проект 2019 для SameSite. Разработчики могут программно управлять значением того же атрибутаSite с помощью HttpCookie.SameSite
свойства. SameSite
Задание свойства Strict
, Lax
или None
приводит к тому, что эти значения записываются в сети с cookieпомощью . Параметр, указывающий SameSiteMode.Unspecified
, что один и тот же сайт не должен отправляться с cookieпомощью .
var cookieOptions = new CookieOptions
{
// Set the secure flag, which Chrome's changes will require for SameSite none.
// Note this will also require you to be running on HTTPS.
Secure = true,
// Set the cookie to HTTP only which is good practice unless you really do need
// to access it client side in scripts.
HttpOnly = true,
// Add the SameSite attribute, this will emit the attribute with a value of none.
SameSite = SameSiteMode.None
// The client should follow its default cookie policy.
// SameSite = SameSiteMode.Unspecified
};
// Add the cookie to the response cookie collection
Response.Cookies.Append("MyCookie", "cookieValue", cookieOptions);
}
Использование API с SameSite
Значение по умолчанию httpContext.Response.Cookies.Add, то есть атрибут SameSite, добавленный в приложениеcookie, и клиент будет использовать его поведение по умолчанию Unspecified
(Lax для новых браузеров, None для старых). В следующем коде показано, как изменить значение SameSite cookie на SameSiteMode.Lax
:
HttpContext.Response.Cookies.Append(
"name", "value",
new CookieOptions() { SameSite = SameSiteMode.Lax });
Все компоненты ASP.NET Core, которые выдают файлы cookie, переопределяют предыдущие значения по умолчанию с параметрами, соответствующими их сценариям. Переопределенные предыдущие значения по умолчанию не изменились.
Компонент | cookie | По умолчанию. |
---|---|---|
CookieBuilder | SameSite | Unspecified |
Session | SessionOptions.Cookie | Lax |
CookieTempDataProvider | CookieTempDataProviderOptions.Cookie | Lax |
IAntiforgery | AntiforgeryOptions.Cookie | Strict |
Cookie Проверка подлинности | CookieAuthenticationOptions.Cookie | Lax |
AddTwitter | TwitterOptions.StateCookie | Lax |
RemoteAuthenticationHandler<TOptions> | RemoteAuthenticationOptions.CorrelationCookie | None |
AddOpenIdConnect | OpenIdConnectOptions.NonceCookie | None |
HttpContext.Response.Cookies.Append | CookieOptions | Unspecified |
ASP.NET Core 3.1 и более поздних версий предоставляет следующую поддержку SameSite:
- Переопределяет поведение выдачи
SameSiteMode.None
SameSite=None
- Добавляет новое значение
SameSiteMode.Unspecified
для пропуска атрибута SameSite. - Все API файлов cookie по умолчанию
Unspecified
. Некоторые компоненты, использующие файлы cookie, задают значения, относящиеся к их сценариям. Примеры см. в приведенной выше таблице.
В ASP.NET Core 3.0 и более поздних версий значения по умолчанию SameSite были изменены, чтобы избежать конфликтов с несогласованными значениями по умолчанию клиента. Следующие API изменили значение по умолчанию, SameSiteMode.Lax
чтобы -1
избежать создания атрибута SameSite для этих файлов cookie:
- CookieOptions используется с HttpContext.Response.Cookies.Append
- CookieBuilder используется в качестве фабрики для
CookieOptions
- CookiePolicyOptions.MinimumSameSitePolicy
Журнал и изменения
Поддержка SameSite была впервые реализована в ASP.NET Core в версии 2.0 с использованием стандартного проекта 2016 года. Стандарт 2016 года был отклонен. ASP.NET Core, выбрав несколько файлов cookie Lax
по умолчанию. После возникновения нескольких проблем с проверкой подлинности большинство использования SameSite было отключено.
Исправления были выпущены в ноябре 2019 года, чтобы обновить стандарт 2016 года до стандарта 2019 года. Проект спецификации SameSite в 2019 году:
- Не совместим с черновиком 2016 года. Дополнительные сведения см. в разделе "Поддержка старых браузеров " в этом документе.
- Указывает, что файлы cookie обрабатываются по
SameSite=Lax
умолчанию. - Указывает файлы cookie, которые явно утверждаются
SameSite=None
для включения доставки между сайтами, должны быть помечены какSecure
.None
является новой записью, чтобы отказаться. - Поддерживается исправлениями, выпущенными для ASP.NET Core 2.1, 2.2 и 3.0. ASP.NET Core 3.1 и более поздних версий имеет дополнительную поддержку SameSite.
- Планируется включить Chrome по умолчанию в феврале 2020 года. Браузеры начали переходить к этому стандарту в 2019 году.
API, затронутые изменением стандарта 2016 SameSite в стандарт 2019 г.
- Http.SameSiteMode
- CookieOptions.SameSite
- CookieBuilder.SameSite
- CookiePolicyOptions.MinimumSameSitePolicy
- Microsoft.Net.Http.Headers.SameSiteMode
- Microsoft.Net.Http.Headers.SetCookieHeaderValue.SameSite
Поддержка старых браузеров
Стандарт 2016 SameSite подтвердил, что неизвестные значения должны рассматриваться как SameSite=Strict
значения. Приложения, доступные из старых браузеров, которые поддерживают стандарт SameSite 2016, могут нарушиться при получении свойства SameSite со значением None
. Веб-приложения должны реализовать обнаружение браузеров, если они намерены поддерживать старые браузеры. ASP.NET Core не реализует обнаружение браузера, так как значения пользовательских агентов являются очень неустойчивыми и часто изменяются. Точка Microsoft.AspNetCore.CookiePolicy расширения позволяет подключаться к логике конкретного агента пользователя.
Добавьте Program.cs
код, который вызывается UseCookiePolicy перед вызовом UseAuthentication или любым методом, который записывает файлы cookie:
var builder = WebApplication.CreateBuilder(args);
builder.Services.Configure<CookiePolicyOptions>(options =>
{
options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
options.OnAppendCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
options.OnDeleteCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
});
void CheckSameSite(HttpContext httpContext, CookieOptions options)
{
if (options.SameSite == SameSiteMode.None)
{
var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
options.SameSite = SameSiteMode.Unspecified;
}
}
}
builder.Services.AddRazorPages();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCookiePolicy();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
Добавьте Program.cs
код, аналогичный следующему выделенному коду:
var builder = WebApplication.CreateBuilder(args);
builder.Services.Configure<CookiePolicyOptions>(options =>
{
options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
options.OnAppendCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
options.OnDeleteCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
});
void CheckSameSite(HttpContext httpContext, CookieOptions options)
{
if (options.SameSite == SameSiteMode.None)
{
var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
options.SameSite = SameSiteMode.Unspecified;
}
}
}
builder.Services.AddRazorPages();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCookiePolicy();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
В предыдущем примере представлена пользовательская библиотека, которая определяет, MyUserAgentDetectionLib.DisallowsSameSiteNone
не поддерживает ли агент пользователя тот же сайт None
:
if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
options.SameSite = SameSiteMode.Unspecified;
}
В следующем коде показан пример DisallowsSameSiteNone
метода:
Предупреждение
Следующий код предназначен только для демонстрации:
- Его не следует считать полным.
- Он не поддерживается или не поддерживается.
public static bool DisallowsSameSiteNone(string userAgent)
{
// Check if a null or empty string has been passed in, since this
// will cause further interrogation of the useragent to fail.
if (String.IsNullOrWhiteSpace(userAgent))
return false;
// Cover all iOS based browsers here. This includes:
// - Safari on iOS 12 for iPhone, iPod Touch, iPad
// - WkWebview on iOS 12 for iPhone, iPod Touch, iPad
// - Chrome on iOS 12 for iPhone, iPod Touch, iPad
// All of which are broken by SameSite=None, because they use the iOS networking
// stack.
if (userAgent.Contains("CPU iPhone OS 12") ||
userAgent.Contains("iPad; CPU OS 12"))
{
return true;
}
// Cover Mac OS X based browsers that use the Mac OS networking stack.
// This includes:
// - Safari on Mac OS X.
// This does not include:
// - Chrome on Mac OS X
// Because they do not use the Mac OS networking stack.
if (userAgent.Contains("Macintosh; Intel Mac OS X 10_14") &&
userAgent.Contains("Version/") && userAgent.Contains("Safari"))
{
return true;
}
// Cover Chrome 50-69, because some versions are broken by SameSite=None,
// and none in this range require it.
// Note: this covers some pre-Chromium Edge versions,
// but pre-Chromium Edge does not require SameSite=None.
if (userAgent.Contains("Chrome/5") || userAgent.Contains("Chrome/6"))
{
return true;
}
return false;
}
Тестирование приложений для проблем с SameSite
Приложения, взаимодействующие с удаленными сайтами, например с помощью стороннего входа, должны:
- Проверьте взаимодействие в нескольких браузерах.
- Примените обнаружение и устранение рисков браузера CookiePolicy, описанные в этом документе.
Тестирование веб-приложений с помощью клиентской версии, которая может принять участие в новом поведении SameSite. Chrome, Firefox и Chromium Edge имеют новые флаги функций, которые можно использовать для тестирования. После применения приложений исправлений SameSite протестируйте его с более старыми версиями клиента, особенно Safari. Дополнительные сведения см. в разделе "Поддержка старых браузеров " в этом документе.
Тестирование с помощью Chrome
Chrome 78+ дает вводящие в заблуждение результаты, так как он имеет временное устранение рисков. Временное устранение рисков Chrome 78+ позволяет использовать файлы cookie менее чем за две минуты. Chrome 76 или 77 с соответствующими флагами тестирования обеспечивает более точные результаты. Чтобы проверить новое поведение SameSite, chrome://flags/#same-site-by-default-cookies
включено. Более старые версии Chrome (75 и ниже) сообщаются о сбое с новым None
параметром. См. статью "Поддержка старых браузеров " в этом документе.
Google не делает более старые версии хрома доступными. Следуйте инструкциям в разделе "Скачать Chromium" , чтобы протестировать старые версии Chrome. Не скачивайте Chrome из ссылок, предоставляемых поиском более старых версий хрома.
Начиная с канарской версии 80.0.3975.0
, временное устранение рисков Lax+POST можно отключить для тестирования с помощью нового флага --enable-features=SameSiteDefaultChecksMethodRigorously
, чтобы разрешить тестирование сайтов и служб в конечном итоге состояния функции, в которой была удалена устранение рисков. Дополнительные сведения см. в разделе "Обновления Chromium Projects SameSite"
Тестирование с помощью Safari
Safari 12 строго реализует предыдущий черновик и завершается ошибкойcookie, если новое None
значение находится в . None
Не используется код обнаружения браузера, поддерживающий старые браузеры в этом документе. Проверьте имена входа в стиль ОС на основе Safari 12, Safari 13 и WebKit с помощью MSAL, ADAL или любой используемой библиотеки. Эта проблема зависит от базовой версии ОС. OSX Mojave (10.14) и iOS 12, как известно, имеют проблемы совместимости с новым поведением SameSite. Обновление ОС до OSX Catalina (10.15) или iOS 13 устраняет проблему. В настоящее время Safari не имеет флаг согласия на тестирование нового поведения спецификации.
Тестирование с помощью Firefox
Поддержка Firefox для нового стандарта может быть проверена на версии 68+ путем согласия на about:config
странице с флагом network.cookie.sameSite.laxByDefault
функции. Не было отчетов о проблемах совместимости с более старыми версиями Firefox.
Тестирование с помощью браузера Edge
Edge поддерживает старый стандарт SameSite. У пограничных версий 44 нет известных проблем совместимости с новым стандартом.
Тестирование с помощью Edge (Chromium)
На странице задаются edge://flags/#same-site-by-default-cookies
флаги SameSite. Проблемы совместимости не обнаружены с пограничным Chromium.
Тестирование с помощью Electron
Electron Версии включают более старые версии Chromium. Например, версия Electron , используемая Teams, — Chromium 66, которая демонстрирует старое поведение. Необходимо выполнить собственное тестирование совместимости с версией используемого Electron продукта. См . раздел "Поддержка старых браузеров " в следующем разделе.
Дополнительные ресурсы
- Блог Chromium:Developers: Get Ready for New SameSite=None; Безопасные Cookie параметры
- Описаны файлы cookie SameSite
- Исправления за ноябрь 2019 г.
Пример | Документ |
---|---|
Страницы .NET Core Razor | пример ASP.NET Core 3.1 Razor Pages SameSite cookie |
Следующий пример можно скачать и проверить:
Пример | Документ |
---|---|
Страницы .NET Core Razor | пример ASP.NET Core 3.1 Razor Pages SameSite cookie |
Поддержка .NET Core для того же атрибута.
.NET Core 3.1 и более поздних версий поддерживают стандарт 2019 для SameSite. Разработчики могут программно управлять значением того же атрибутаSite с помощью HttpCookie.SameSite
свойства. SameSite
Задание свойства Strict, Lax или None приводит к записи этих значений в сети с помощью параметра cookie. Задание равно, указывающее (SameSiteMode)(-1)
, что в сети не должен быть включен ни один атрибут одного и того же сайта. cookie
var cookieOptions = new CookieOptions
{
// Set the secure flag, which Chrome's changes will require for SameSite none.
// Note this will also require you to be running on HTTPS.
Secure = true,
// Set the cookie to HTTP only which is good practice unless you really do need
// to access it client side in scripts.
HttpOnly = true,
// Add the SameSite attribute, this will emit the attribute with a value of none.
// To not emit the attribute at all set
// SameSite = (SameSiteMode)(-1)
SameSite = SameSiteMode.None
};
// Add the cookie to the response cookie collection
Response.Cookies.Append("MyCookie", "cookieValue", cookieOptions);
.NET Core 3.1 и более поздних версий поддерживают обновленные значения SameSite и добавляют дополнительное значение перечисления в SameSiteMode.Unspecified
перечисление SameSiteMode
.
Это новое значение указывает, что с ним не должен отправляться cookieтот же сайт.
Использование API с SameSite
Значение по умолчанию httpContext.Response.Cookies.Add, то есть атрибут SameSite, добавленный в приложениеcookie, и клиент будет использовать его поведение по умолчанию Unspecified
(Lax для новых браузеров, None для старых). В следующем коде показано, как изменить значение SameSite cookie на SameSiteMode.Lax
:
HttpContext.Response.Cookies.Append(
"name", "value",
new CookieOptions() { SameSite = SameSiteMode.Lax });
Все компоненты ASP.NET Core, которые выдают файлы cookie, переопределяют предыдущие значения по умолчанию с параметрами, соответствующими их сценариям. Переопределенные предыдущие значения по умолчанию не изменились.
Компонент | cookie | По умолчанию. |
---|---|---|
CookieBuilder | SameSite | Unspecified |
Session | SessionOptions.Cookie | Lax |
CookieTempDataProvider | CookieTempDataProviderOptions.Cookie | Lax |
IAntiforgery | AntiforgeryOptions.Cookie | Strict |
Cookie Проверка подлинности | CookieAuthenticationOptions.Cookie | Lax |
AddTwitter | TwitterOptions.StateCookie | Lax |
RemoteAuthenticationHandler<TOptions> | RemoteAuthenticationOptions.CorrelationCookie | None |
AddOpenIdConnect | OpenIdConnectOptions.NonceCookie | None |
HttpContext.Response.Cookies.Append | CookieOptions | Unspecified |
ASP.NET Core 3.1 и более поздних версий предоставляет следующую поддержку SameSite:
- Переопределяет поведение выдачи
SameSiteMode.None
SameSite=None
- Добавляет новое значение
SameSiteMode.Unspecified
для пропуска атрибута SameSite. - Все API файлов cookie по умолчанию
Unspecified
. Некоторые компоненты, использующие файлы cookie, задают значения, относящиеся к их сценариям. Примеры см. в приведенной выше таблице.
В ASP.NET Core 3.0 и более поздних версий значения по умолчанию SameSite были изменены, чтобы избежать конфликтов с несогласованными значениями по умолчанию клиента. Следующие API изменили значение по умолчанию, SameSiteMode.Lax
чтобы -1
избежать создания атрибута SameSite для этих файлов cookie:
- CookieOptions используется с HttpContext.Response.Cookies.Append
- CookieBuilder используется в качестве фабрики для
CookieOptions
- CookiePolicyOptions.MinimumSameSitePolicy
Журнал и изменения
Поддержка SameSite была впервые реализована в ASP.NET Core в версии 2.0 с использованием стандартного проекта 2016 года. Стандарт 2016 года был отклонен. ASP.NET Core, выбрав несколько файлов cookie Lax
по умолчанию. После возникновения нескольких проблем с проверкой подлинности большинство использования SameSite было отключено.
Исправления были выпущены в ноябре 2019 года, чтобы обновить стандарт 2016 года до стандарта 2019 года. Проект спецификации SameSite в 2019 году:
- Не совместим с черновиком 2016 года. Дополнительные сведения см. в разделе "Поддержка старых браузеров " в этом документе.
- Указывает, что файлы cookie обрабатываются по
SameSite=Lax
умолчанию. - Указывает файлы cookie, которые явно утверждаются
SameSite=None
для включения доставки между сайтами, должны быть помечены какSecure
.None
является новой записью, чтобы отказаться. - Поддерживается исправлениями, выпущенными для ASP.NET Core 2.1, 2.2 и 3.0. ASP.NET Core 3.1 имеет дополнительную поддержку SameSite.
- Планируется включить Chrome по умолчанию в феврале 2020 года. Браузеры начали переходить к этому стандарту в 2019 году.
API, затронутые изменением стандарта 2016 SameSite в стандарт 2019 г.
- Http.SameSiteMode
- CookieOptions.SameSite
- CookieBuilder.SameSite
- CookiePolicyOptions.MinimumSameSitePolicy
- Microsoft.Net.Http.Headers.SameSiteMode
- Microsoft.Net.Http.Headers.SetCookieHeaderValue.SameSite
Поддержка старых браузеров
Стандарт 2016 SameSite подтвердил, что неизвестные значения должны рассматриваться как SameSite=Strict
значения. Приложения, доступные из старых браузеров, которые поддерживают стандарт SameSite 2016, могут нарушиться при получении свойства SameSite со значением None
. Веб-приложения должны реализовать обнаружение браузеров, если они намерены поддерживать старые браузеры. ASP.NET Core не реализует обнаружение браузера, так как значения пользовательских агентов являются очень неустойчивыми и часто изменяются. Точка Microsoft.AspNetCore.CookiePolicy расширения позволяет подключаться к логике конкретного агента пользователя.
Добавьте Startup.Configure
код, который вызывается UseCookiePolicy перед вызовом UseAuthentication или любым методом, который записывает файлы cookie:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
Добавьте Startup.ConfigureServices
код, аналогичный следующему:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
options.OnAppendCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
options.OnDeleteCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
});
services.AddRazorPages();
}
private void CheckSameSite(HttpContext httpContext, CookieOptions options)
{
if (options.SameSite == SameSiteMode.None)
{
var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
options.SameSite = SameSiteMode.Unspecified;
}
}
}
В предыдущем примере представлена пользовательская библиотека, которая определяет, MyUserAgentDetectionLib.DisallowsSameSiteNone
не поддерживает ли агент пользователя тот же сайт None
:
if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
options.SameSite = SameSiteMode.Unspecified;
}
В следующем коде показан пример DisallowsSameSiteNone
метода:
Предупреждение
Следующий код предназначен только для демонстрации:
- Его не следует считать полным.
- Он не поддерживается или не поддерживается.
public static bool DisallowsSameSiteNone(string userAgent)
{
// Check if a null or empty string has been passed in, since this
// will cause further interrogation of the useragent to fail.
if (String.IsNullOrWhiteSpace(userAgent))
return false;
// Cover all iOS based browsers here. This includes:
// - Safari on iOS 12 for iPhone, iPod Touch, iPad
// - WkWebview on iOS 12 for iPhone, iPod Touch, iPad
// - Chrome on iOS 12 for iPhone, iPod Touch, iPad
// All of which are broken by SameSite=None, because they use the iOS networking
// stack.
if (userAgent.Contains("CPU iPhone OS 12") ||
userAgent.Contains("iPad; CPU OS 12"))
{
return true;
}
// Cover Mac OS X based browsers that use the Mac OS networking stack.
// This includes:
// - Safari on Mac OS X.
// This does not include:
// - Chrome on Mac OS X
// Because they do not use the Mac OS networking stack.
if (userAgent.Contains("Macintosh; Intel Mac OS X 10_14") &&
userAgent.Contains("Version/") && userAgent.Contains("Safari"))
{
return true;
}
// Cover Chrome 50-69, because some versions are broken by SameSite=None,
// and none in this range require it.
// Note: this covers some pre-Chromium Edge versions,
// but pre-Chromium Edge does not require SameSite=None.
if (userAgent.Contains("Chrome/5") || userAgent.Contains("Chrome/6"))
{
return true;
}
return false;
}
Тестирование приложений для проблем с SameSite
Приложения, взаимодействующие с удаленными сайтами, например с помощью стороннего входа, должны:
- Проверьте взаимодействие в нескольких браузерах.
- Примените обнаружение и устранение рисков браузера CookiePolicy, описанные в этом документе.
Тестирование веб-приложений с помощью клиентской версии, которая может принять участие в новом поведении SameSite. Chrome, Firefox и Chromium Edge имеют новые флаги функций, которые можно использовать для тестирования. После применения приложений исправлений SameSite протестируйте его с более старыми версиями клиента, особенно Safari. Дополнительные сведения см. в разделе "Поддержка старых браузеров " в этом документе.
Тестирование с помощью Chrome
Chrome 78+ дает вводящие в заблуждение результаты, так как он имеет временное устранение рисков. Временное устранение рисков Chrome 78+ позволяет использовать файлы cookie менее чем за две минуты. Chrome 76 или 77 с соответствующими флагами тестирования обеспечивает более точные результаты. Чтобы проверить новое поведение SameSite, chrome://flags/#same-site-by-default-cookies
включено. Более старые версии Chrome (75 и ниже) сообщаются о сбое с новым None
параметром. См. статью "Поддержка старых браузеров " в этом документе.
Google не делает более старые версии хрома доступными. Следуйте инструкциям в разделе "Скачать Chromium" , чтобы протестировать старые версии Chrome. Не скачивайте Chrome из ссылок, предоставляемых поиском более старых версий хрома.
Начиная с канарской версии 80.0.3975.0
, временное устранение рисков Lax+POST можно отключить для тестирования с помощью нового флага --enable-features=SameSiteDefaultChecksMethodRigorously
, чтобы разрешить тестирование сайтов и служб в конечном итоге состояния функции, в которой была удалена устранение рисков. Дополнительные сведения см. в разделе "Обновления Chromium Projects SameSite"
Тестирование с помощью Safari
Safari 12 строго реализует предыдущий черновик и завершается ошибкойcookie, если новое None
значение находится в . None
Не используется код обнаружения браузера, поддерживающий старые браузеры в этом документе. Проверьте имена входа в стиль ОС на основе Safari 12, Safari 13 и WebKit с помощью MSAL, ADAL или любой используемой библиотеки. Эта проблема зависит от базовой версии ОС. OSX Mojave (10.14) и iOS 12, как известно, имеют проблемы совместимости с новым поведением SameSite. Обновление ОС до OSX Catalina (10.15) или iOS 13 устраняет проблему. В настоящее время Safari не имеет флаг согласия на тестирование нового поведения спецификации.
Тестирование с помощью Firefox
Поддержка Firefox для нового стандарта может быть проверена на версии 68+ путем согласия на about:config
странице с флагом network.cookie.sameSite.laxByDefault
функции. Не было отчетов о проблемах совместимости с более старыми версиями Firefox.
Тестирование с помощью браузера Edge
Edge поддерживает старый стандарт SameSite. У пограничных версий 44 нет известных проблем совместимости с новым стандартом.
Тестирование с помощью Edge (Chromium)
На странице задаются edge://flags/#same-site-by-default-cookies
флаги SameSite. Проблемы совместимости не обнаружены с пограничным Chromium.
Тестирование с помощью Electron
Electron Версии включают более старые версии Chromium. Например, версия Electron , используемая Teams, — Chromium 66, которая демонстрирует старое поведение. Необходимо выполнить собственное тестирование совместимости с версией используемого Electron продукта. См . раздел "Поддержка старых браузеров " в следующем разделе.
Дополнительные ресурсы
- Блог Chromium:Developers: Get Ready for New SameSite=None; Безопасные Cookie параметры
- Описаны файлы cookie SameSite
- Исправления за ноябрь 2019 г.
Пример | Документ |
---|---|
Страницы .NET Core Razor | пример ASP.NET Core 3.1 Razor Pages SameSite cookie |
Можно скачать и проверить следующие примеры:
Пример | Документ |
---|---|
MVC .NET Core | пример MVC SameSite cookie ASP.NET Core 2.1 |
Страницы .NET Core Razor | пример ASP.NET Core 2.1 Razor Pages SameSite cookie |
Изменения в поведении исправлений за декабрь
Изменение конкретного поведения для платформа .NET Framework и .NET Core 2.1 заключается в том, как SameSite
свойство интерпретирует None
значение. Перед исправлением значение None
означает "Не выдавать атрибут вообще", после исправления оно означает "Выпустить атрибут со значением None
". После исправления SameSite
значение (SameSiteMode)(-1)
атрибута не будет выдаваться.
Значение sameSite по умолчанию для проверки подлинности форм и файлов cookie состояния сеанса было изменено на None
Lax
.
Использование API с SameSite
Значение по умолчанию httpContext.Response.Cookies.Add, то есть атрибут SameSite, добавленный в приложениеcookie, и клиент будет использовать его поведение по умолчанию Unspecified
(Lax для новых браузеров, None для старых). В следующем коде показано, как изменить значение SameSite cookie на SameSiteMode.Lax
:
HttpContext.Response.Cookies.Append(
"name", "value",
new CookieOptions() { SameSite = SameSiteMode.Lax });
Все компоненты ASP.NET Core, которые выдают файлы cookie, переопределяют предыдущие значения по умолчанию с параметрами, соответствующими их сценариям. Переопределенные предыдущие значения по умолчанию не изменились.
Компонент | cookie | По умолчанию. |
---|---|---|
CookieBuilder | SameSite | Unspecified |
Session | SessionOptions.Cookie | Lax |
CookieTempDataProvider | CookieTempDataProviderOptions.Cookie | Lax |
IAntiforgery | AntiforgeryOptions.Cookie | Strict |
Cookie Проверка подлинности | CookieAuthenticationOptions.Cookie | Lax |
AddTwitter | TwitterOptions.StateCookie | Lax |
RemoteAuthenticationHandler<TOptions> | RemoteAuthenticationOptions.CorrelationCookie | None |
AddOpenIdConnect | OpenIdConnectOptions.NonceCookie | None |
HttpContext.Response.Cookies.Append | CookieOptions | Unspecified |
Журнал и изменения
Поддержка SameSite была впервые реализована в ASP.NET Core в версии 2.0 с использованием стандартного проекта 2016 года. Стандарт 2016 года был отклонен. ASP.NET Core, выбрав несколько файлов cookie Lax
по умолчанию. После возникновения нескольких проблем с проверкой подлинности большинство использования SameSite было отключено.
Исправления были выпущены в ноябре 2019 года, чтобы обновить стандарт 2016 года до стандарта 2019 года. Проект спецификации SameSite в 2019 году:
- Не совместим с черновиком 2016 года. Дополнительные сведения см. в разделе "Поддержка старых браузеров " в этом документе.
- Указывает, что файлы cookie обрабатываются по
SameSite=Lax
умолчанию. - Указывает файлы cookie, которые явно утверждаются
SameSite=None
для включения доставки между сайтами, должны быть помечены какSecure
.None
является новой записью, чтобы отказаться. - Поддерживается исправлениями, выпущенными для ASP.NET Core 2.1, 2.2 и 3.0. ASP.NET Core 3.1 имеет дополнительную поддержку SameSite.
- Планируется включить Chrome по умолчанию в феврале 2020 года. Браузеры начали переходить к этому стандарту в 2019 году.
API, затронутые изменением стандарта 2016 SameSite в стандарт 2019 г.
- Http.SameSiteMode
- CookieOptions.SameSite
- CookieBuilder.SameSite
- CookiePolicyOptions.MinimumSameSitePolicy
- Microsoft.Net.Http.Headers.SameSiteMode
- Microsoft.Net.Http.Headers.SetCookieHeaderValue.SameSite
Поддержка старых браузеров
Стандарт 2016 SameSite подтвердил, что неизвестные значения должны рассматриваться как SameSite=Strict
значения. Приложения, доступные из старых браузеров, которые поддерживают стандарт SameSite 2016, могут нарушиться при получении свойства SameSite со значением None
. Веб-приложения должны реализовать обнаружение браузеров, если они намерены поддерживать старые браузеры. ASP.NET Core не реализует обнаружение браузера, так как значения пользовательских агентов являются очень неустойчивыми и часто изменяются. Точка Microsoft.AspNetCore.CookiePolicy расширения позволяет подключаться к логике конкретного агента пользователя.
Добавьте Startup.Configure
код, который вызывается UseCookiePolicy перед вызовом UseAuthentication или любым методом, который записывает файлы cookie:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
Добавьте Startup.ConfigureServices
код, аналогичный следующему:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.MinimumSameSitePolicy = (SameSiteMode)(-1);
options.OnAppendCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
options.OnDeleteCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
});
services.AddRazorPages();
}
private void CheckSameSite(HttpContext httpContext, CookieOptions options)
{
if (options.SameSite == SameSiteMode.None)
{
var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
options.SameSite = (SameSiteMode)(-1);
}
}
}
В предыдущем примере представлена пользовательская библиотека, которая определяет, MyUserAgentDetectionLib.DisallowsSameSiteNone
не поддерживает ли агент пользователя тот же сайт None
:
if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
options.SameSite = SameSiteMode.Unspecified;
}
В следующем коде показан пример DisallowsSameSiteNone
метода:
Предупреждение
Следующий код предназначен только для демонстрации:
- Его не следует считать полным.
- Он не поддерживается или не поддерживается.
public static bool DisallowsSameSiteNone(string userAgent)
{
// Check if a null or empty string has been passed in, since this
// will cause further interrogation of the useragent to fail.
if (String.IsNullOrWhiteSpace(userAgent))
return false;
// Cover all iOS based browsers here. This includes:
// - Safari on iOS 12 for iPhone, iPod Touch, iPad
// - WkWebview on iOS 12 for iPhone, iPod Touch, iPad
// - Chrome on iOS 12 for iPhone, iPod Touch, iPad
// All of which are broken by SameSite=None, because they use the iOS networking
// stack.
if (userAgent.Contains("CPU iPhone OS 12") ||
userAgent.Contains("iPad; CPU OS 12"))
{
return true;
}
// Cover Mac OS X based browsers that use the Mac OS networking stack.
// This includes:
// - Safari on Mac OS X.
// This does not include:
// - Chrome on Mac OS X
// Because they do not use the Mac OS networking stack.
if (userAgent.Contains("Macintosh; Intel Mac OS X 10_14") &&
userAgent.Contains("Version/") && userAgent.Contains("Safari"))
{
return true;
}
// Cover Chrome 50-69, because some versions are broken by SameSite=None,
// and none in this range require it.
// Note: this covers some pre-Chromium Edge versions,
// but pre-Chromium Edge does not require SameSite=None.
if (userAgent.Contains("Chrome/5") || userAgent.Contains("Chrome/6"))
{
return true;
}
return false;
}
Тестирование приложений для проблем с SameSite
Приложения, взаимодействующие с удаленными сайтами, например с помощью стороннего входа, должны:
- Проверьте взаимодействие в нескольких браузерах.
- Примените обнаружение и устранение рисков браузера CookiePolicy, описанные в этом документе.
Тестирование веб-приложений с помощью клиентской версии, которая может принять участие в новом поведении SameSite. Chrome, Firefox и Chromium Edge имеют новые флаги функций, которые можно использовать для тестирования. После применения приложений исправлений SameSite протестируйте его с более старыми версиями клиента, особенно Safari. Дополнительные сведения см. в разделе "Поддержка старых браузеров " в этом документе.
Тестирование с помощью Chrome
Chrome 78+ дает вводящие в заблуждение результаты, так как он имеет временное устранение рисков. Временное устранение рисков Chrome 78+ позволяет использовать файлы cookie менее чем за две минуты. Chrome 76 или 77 с соответствующими флагами тестирования обеспечивает более точные результаты. Чтобы проверить новое поведение SameSite, chrome://flags/#same-site-by-default-cookies
включено. Более старые версии Chrome (75 и ниже) сообщаются о сбое с новым None
параметром. См. статью "Поддержка старых браузеров " в этом документе.
Google не делает более старые версии хрома доступными. Следуйте инструкциям в разделе "Скачать Chromium" , чтобы протестировать старые версии Chrome. Не скачивайте Chrome из ссылок, предоставляемых поиском более старых версий хрома.
Начиная с канарской версии 80.0.3975.0
, временное устранение рисков Lax+POST можно отключить для тестирования с помощью нового флага --enable-features=SameSiteDefaultChecksMethodRigorously
, чтобы разрешить тестирование сайтов и служб в конечном итоге состояния функции, в которой была удалена устранение рисков. Дополнительные сведения см. в разделе "Обновления Chromium Projects SameSite"
Тестирование с помощью Safari
Safari 12 строго реализует предыдущий черновик и завершается ошибкойcookie, если новое None
значение находится в . None
Не используется код обнаружения браузера, поддерживающий старые браузеры в этом документе. Проверьте имена входа в стиль ОС на основе Safari 12, Safari 13 и WebKit с помощью MSAL, ADAL или любой используемой библиотеки. Эта проблема зависит от базовой версии ОС. OSX Mojave (10.14) и iOS 12, как известно, имеют проблемы совместимости с новым поведением SameSite. Обновление ОС до OSX Catalina (10.15) или iOS 13 устраняет проблему. В настоящее время Safari не имеет флаг согласия на тестирование нового поведения спецификации.
Тестирование с помощью Firefox
Поддержка Firefox для нового стандарта может быть проверена на версии 68+ путем согласия на about:config
странице с флагом network.cookie.sameSite.laxByDefault
функции. Не было отчетов о проблемах совместимости с более старыми версиями Firefox.
Тестирование с помощью браузера Edge
Edge поддерживает старый стандарт SameSite. У пограничных версий 44 нет известных проблем совместимости с новым стандартом.
Тестирование с помощью Edge (Chromium)
На странице задаются edge://flags/#same-site-by-default-cookies
флаги SameSite. Проблемы совместимости не обнаружены с пограничным Chromium.
Тестирование с помощью Electron
Electron Версии включают более старые версии Chromium. Например, версия Electron , используемая Teams, — Chromium 66, которая демонстрирует старое поведение. Необходимо выполнить собственное тестирование совместимости с версией используемого Electron продукта. См . раздел "Поддержка старых браузеров " в следующем разделе.
Дополнительные ресурсы
- Блог Chromium:Developers: Get Ready for New SameSite=None; Безопасные Cookie параметры
- Описаны файлы cookie SameSite
- Исправления за ноябрь 2019 г.
Пример | Документ |
---|---|
MVC .NET Core | пример MVC SameSite cookie ASP.NET Core 2.1 |
Страницы .NET Core Razor | пример ASP.NET Core 2.1 Razor Pages SameSite cookie |
ASP.NET Core