SameSite는HTTP 쿠키에대한 2016확장입니다CSRF (Cross Site Request Forgery)를 완화하기위한 것입니다.원래 디자인은 쿠키에 새로운 SameSite 속성을 추가하여 사용할 수있는 옵트 인 기능이었습니다.Lax와 Strict의 두 값이있었습니다.값을 Lax로 설정하면 쿠키가 동일한 사이트 내 탐색시 또는 다른 사이트에서 사이트로 GET 탐색을 통해 전송되어야 함을 나타냅니다.Strict 값은 쿠키를 동일한 사이트에서만 발생하는 요청으로 제한했습니다.속성을 전혀 설정하지 않으면 요청에서 쿠키가 흐르는 방식에 제한이 없습니다.OpenIdConnect 인증 작업 (예 : 로그인, 로그 아웃) 및 외부 사이트에서 작업을 요청하는 사이트로 POST 요청을 보내는 기타 기능은 상관 및 / 또는 CSRF 보호를 위해 쿠키를 사용할 수 있습니다.이러한 작업은 속성을 전혀 설정하지 않음으로써 SameSite를 옵트 아웃해야합니다.
Google은 이제표준을 업데이트하고 있습니다예정된 Chrome 버전에서 제안 된 변경 사항을 구현합니다.변경하면 새 SameSite 값인 "없음"이 추가되고 기본 동작이 "Lax"로 변경됩니다.이로 인해 OpenIdConnect 로그인 및 웹 사이트가 신뢰할 수있는 다른 기능이 손상 될 수 있습니다. 이러한 기능은 SameSite 속성 값이 "None"으로 설정된 쿠키를 사용해야합니다.그러나 원래 표준을 준수하고 새 값을 인식하지 못하는 브라우저는 SameSite 표준에 따라 새 표준을 사용하는 브라우저와는 다른 동작을합니다. 브라우저가 SameSite에 대한 값을 볼 경우 해당 값을 "엄격한".즉, .NET 웹 사이트에서 새 없음 값을 보낼지 또는 속성을 전혀 보내지 않을지를 결정하기 위해 사용자 에이전트 스니핑을 추가해야합니다.
.NET은 .NET 4.7.2 및 .NET Core 2.1 이상에서 SameSite 속성 동작의 동작을 변경하여 Google의 새로운 가치 도입을 반영하기 위해 업데이트를 발행합니다..NET Framework의 업데이트는 12 월 10 일에 제공 될 예정입니다..NET Core 업데이트는 11 월 초 미리보기 1부터 .NET Core 3.1에서 사용할 수 있습니다..NET 3.0 및 2.1 업데이트는 11 월 19 일에 출시 될 예정입니다.
.NET Core 3.1에는SameSite 속성을 설정하지 않는업데이트 된 열거 정의SameSite.Unspecified가 포함됩니다.
Microsoft.Owin v4.1 및 .NET Core 용 OpenIdConnect 미들웨어는 .NET Framework 및 .NET 업데이트와 동시에 업데이트되지만 사용자 에이전트 스니핑 코드를 프레임 워크에 도입 할 수는 없습니다. 사이트 코드.에이전트 스니핑의 구현은 사용중인 ASP.NET 또는 ASP.NET Core 버전과 지원하려는 브라우저에 따라 다릅니다.
Microsoft.Owin 4.1.0이 포함 된 ASP.NET 4.7.2의 경우 에이전트 스니핑은ICookieManager를사용하여 구현할 수 있습니다.
public class SameSiteCookieManager : ICookieManager
{
private readonly ICookieManager _innerManager;
public SameSiteCookieManager() : this(new CookieManager())
{
}
public SameSiteCookieManager(ICookieManager innerManager)
{
_innerManager = innerManager;
}
public void AppendResponseCookie(IOwinContext context, string key, string value,
CookieOptions options)
{
CheckSameSite(context, options);
_innerManager.AppendResponseCookie(context, key, value, options);
}
public void DeleteCookie(IOwinContext context, string key, CookieOptions options)
{
CheckSameSite(context, options);
_innerManager.DeleteCookie(context, key, options);
}
public string GetRequestCookie(IOwinContext context, string key)
{
return _innerManager.GetRequestCookie(context, key);
}
private void CheckSameSite(IOwinContext context, CookieOptions options)
{
if (options.SameSite == SameSiteMode.None && DisallowsSameSiteNone(context))
{
options.SameSite = null;
}
}
public static bool DisallowsSameSiteNone(IOwinContext context)
{
// TODO: Use your User Agent library of choice here.
var userAgent = context.Request.Headers["User-Agent"];
return userAgent.Contains("BrokenUserAgent") ||
userAgent.Contains("BrokenUserAgent2")
}
}
그런 다음 새로운 CookieManager를 사용하도록 OpenIdConnect 설정을 구성하십시오.
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
// … Your preexisting options …
CookieManager = new SameSiteCookieManager(new SystemWebCookieManager())
});
SystemWebCookieManager가 제대로 작동하려면 .NET 4.7.2 이상의 SameSite 패치가 설치되어 있어야합니다.
ASP.NET Core의 경우 패치를 설치 한 다음쿠키 정책내에 에이전트 스니핑 코드를 구현해야합니다.3.1 이전 버전의 경우 SameSiteMode.Unspecified를 (SameSiteMode) (-1)로 바꿉니다.
private void CheckSameSite(HttpContext httpContext, CookieOptions options)
{
if (options.SameSite == SameSiteMode.None)
{
var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
// TODO: Use your User Agent library of choice here.
if (/* UserAgent doesn’t support new behavior */)
{
// For .NET Core < 3.1 set SameSite = (SameSiteMode)(-1)
options.SameSite = SameSiteMode.Unspecified;
}
}
}
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);
});
}
public void Configure(IApplicationBuilder app)
{
app.UseCookiePolicy(); // Before UseAuthentication or anything else that writes cookies.
app.UseAuthentication();
// …
}
Azure Active Directory 팀에서 테스트 한 결과 Azure Active Directory에서 새 값을 이해하지 못하는 것으로 보이는 모든 일반 사용자 에이전트에 대해 다음 검사가 작동한다는 것을 알았습니다.
public static bool DisallowsSameSiteNone(string userAgent)
{
// 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;
}
이 브라우저 목록은 결코 정식이 아니며 업데이트가 완료되면 시스템이 지원하는 공통 브라우저 및 기타 사용자 에이전트가 예상대로 작동하는지 확인해야합니다.
Chrome 80은Chrome 79 베타에 추가 된 임시 완화를 포함하여 2020 년 2 월 또는 3 월에새로운 동작을 시작할 예정입니다.완화없이 새로운 동작을 테스트하려면 Chromium 76을 사용하십시오. 이전 버전의 Chromium을 다운로드 할 수 있습니다.
Chrome이 2020 년 초에 새로운 동작을 수행 할 때까지 프레임 워크 버전을 업데이트 할 수없는 경우 ASP.NET 및 ASP.NET Core에서 사용하는 기본 암시 적 흐름 대신 OpenIdConnect 흐름을 코드 흐름으로 변경할 수 있습니다. 이는 임시 조치로 간주해야합니다.