使用英语阅读

通过


适用于 ASP.NET 4.7.2 VB MVC 的 SameSite Cookie 示例

.NET Framework 4.7 具有对 SameSite 属性的内置支持,但它遵循原始标准。 修补的行为更改了 的含义 SameSite.None ,以发出值为 的属性 None,而不是根本不发出值。 如果不想发出值,可以将 Cookie 上的 属性设置为 SameSite -1。

写入 SameSite 属性

下面是如何在 Cookie 上编写 SameSite 属性的示例:

' Create the cookie
Dim sameSiteCookie As New HttpCookie("sameSiteSample")

' Set a value for the cookie
sameSiteCookie.Value = "sample"

' Set the secure flag, which Chrome's changes will require for SameSite none.
' Note this will also require you to be running on HTTPS
sameSiteCookie.Secure = True

' Set the cookie to HTTP only which is good practice unless you really do need
' to access it client side in scripts.
sameSiteCookie.HttpOnly = True

' Expire the cookie in 1 minute
sameSiteCookie.Expires = Date.Now.AddMinutes(1)

' Add the SameSite attribute, this will emit the attribute with a value of none.
' To Not emit the attribute at all set the SameSite property to -1.
sameSiteCookie.SameSite = SameSiteMode.None

' Add the cookie to the response cookie collection
Response.Cookies.Add(sameSiteCookie)

如果你使用英语以外的语言阅读本文,请在此 GitHub 讨论问题 中告知我们,如果你希望查看母语的代码注释。

会话状态的默认 sameSite 属性在 会话设置的“cookieSameSite”参数中设置 web.config

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

MVC 身份验证

基于 OWIN MVC Cookie 的身份验证使用 Cookie 管理器来更改 Cookie 属性。 SameSiteCookieManager.vb 是此类的实现,可将其复制到自己的项目中。

必须确保 Microsoft.Owin 组件全部升级到版本 4.1.0 或更高版本。 packages.config例如,检查文件以确保所有版本号都匹配。

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <!-- other packages -->
  <package id="Microsoft.Owin.Host.SystemWeb" version="4.1.0" targetFramework="net472" />
  <package id="Microsoft.Owin.Security" version="4.1.0" targetFramework="net472" />
  <package id="Microsoft.Owin.Security.Cookies" version="4.1.0" targetFramework="net472" />
  <package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net472" />
  <package id="Owin" version="1.0" targetFramework="net472" />
</packages>

必须将身份验证组件配置为在启动类中使用 CookieManager;

Public Sub Configuration(app As IAppBuilder)
    app.UseCookieAuthentication(New CookieAuthenticationOptions() With {
        .CookieSameSite = SameSiteMode.None,
        .CookieHttpOnly = True,
        .CookieSecure = CookieSecureOption.Always,
        .CookieManager = New SameSiteCookieManager(New SystemWebCookieManager())
    })
End Sub

必须在支持 Cookie 管理器 的每个 组件上设置,其中包括 CookieAuthentication 和 OpenIdConnectAuthentication。

SystemWebCookieManager 用于避免响应 Cookie 集成的 已知问题

运行示例

如果运行示例项目,请在初始页面上加载浏览器调试器,并使用它查看站点的 Cookie 集合。 若要在 Edge 和 Chrome 中执行此操作,请按 F12,然后选择 Application 选项卡并单击 Storage 部分中 Cookies 选项下的站点 URL。

浏览器调试器 Cookie 列表

从上图中可以看到,单击“创建同一网站 Cookie”按钮时示例创建的 Cookie 的 SameSite 属性值 Lax示例代码中设置的值相匹配。

截获你无法控制的 Cookie

.NET 4.5.2 引入了一个新事件,用于截获标头的写入。 Response.AddOnSendingHeaders 这可用于在 Cookie 返回到客户端计算机之前截获 Cookie。 在示例中,我们将 事件连接到静态方法,该方法检查浏览器是否支持新的 sameSite 更改;如果不支持,则更改 Cookie 以在已设置新 None 值时不发出属性。

有关连接事件的示例,请参阅 global.asaxSameSiteCookieRewriter.vb ,获取处理事件并调整可复制到自己的代码中的 Cookie sameSite 属性的示例。

Sub FilterSameSiteNoneForIncompatibleUserAgents(ByVal sender As Object)
    Dim application As HttpApplication = TryCast(sender, HttpApplication)

    If application IsNot Nothing Then
        Dim userAgent = application.Context.Request.UserAgent

        If SameSite.DisallowsSameSiteNone(userAgent) Then
            application.Response.AddOnSendingHeaders(
                Function(context)
                    Dim cookies = context.Response.Cookies

                    For i = 0 To cookies.Count - 1
                        Dim cookie = cookies(i)

                        If cookie.SameSite = SameSiteMode.None Then
                            cookie.SameSite = CType((-1), SameSiteMode)
                        End If
                    Next
                End Function)
        End If
    End If
End Sub

可以采用大致相同的方式更改特定的命名 Cookie 行为;下面的示例在支持 None 值的浏览器上将默认身份验证 Cookie 从 Lax 调整为 None ,或删除不支持 None的浏览器上的相同Site 属性。

Public Shared Sub AdjustSpecificCookieSettings()
    HttpContext.Current.Response.AddOnSendingHeaders(Function(context)
            Dim cookies = context.Response.Cookies

            For i = 0 To cookies.Count - 1
            Dim cookie = cookies(i)

            If String.Equals(".ASPXAUTH", cookie.Name, StringComparison.Ordinal) Then

                If SameSite.BrowserDetection.DisallowsSameSiteNone(userAgent) Then
                    cookie.SameSite = -1
                Else
                    cookie.SameSite = SameSiteMode.None
                End If

                cookie.Secure = True
            End If
            Next
        End Function)
End Sub

更多信息

Chrome 汇报

OWIN SameSite 文档

ASP.NET 文档

.NET SameSite 修补程序