培训
.NET Core 3.1 中的中断性变更
若要迁移到 3.1 版 .NET Core 或 ASP.NET Core,本文中列出的中断性变更可能会影响到你的应用。
某些浏览器(如 Chrome 和 Firefox)对 Cookie 的 SameSite
实现进行了中断性变更。 这些变更会影响 OpenID Connect 和 WS 联合身份验证等远程身份验证方案,必须通过发送 SameSite=None
来选择退出。 但是,SameSite=None
会在 iOS 12 和其他浏览器的某些较早版本上中断运行。 应用需探查这些版本,并忽略 SameSite
。
有关此问题的讨论,请参阅 dotnet/aspnetcore#14996。
3.1 预览版 1
SameSite
是对 HTTP Cookie 的 2016 草案标准扩展。 它旨在减少跨站点请求伪造 (CSRF)。 它最初设计成一项功能,服务器可通过添加新参数选择加入该功能。 ASP.NET Core 2.0 添加了对 SameSite
的初始支持。
Google 提出了一项不向后兼容的新草案标准。 该标准将默认模式更改为 Lax
并添加了用于选择退出的新条目 None
。Lax
可满足大多数应用 Cookie;但是,它会造成 OpenID Connect 和 WS 联合身份验证登录等跨站点方案中断。 由于请求流程不同,大多数 OAuth 登录不受影响。 新的 None
参数会导致实现先前草案标准的客户端(例如 iOS 12)出现兼容性问题。 Chrome 80 将包含这些更改。 有关 Chrome 产品发布日程表,请查看 SameSite 更新。
已更新 ASP.NET Core 3.1 来实现新的 SameSite
行为。 该更新重新定义了 SameSiteMode.None
的行为以发出 SameSite=None
,并添加了一个新值 SameSiteMode.Unspecified
以忽略 SameSite
属性。 现在,所有 Cookie API 都默认为 Unspecified
,但某些使用 Cookie 的组件设置了更特定于其方案的值,例如 OpenID Connect 相关性和 nonce Cookie。
有关此方面的其他最新更改,请参阅 HTTP:某些 Cookie SameSite 默认值已更改为“None”。 在 ASP.NET Core 3.0 中,大多数默认值已从 SameSiteMode.Lax 更改为 SameSiteMode.None(但仍使用之前的标准)。
浏览器和规范更改如前文所述。
与远程站点交互(例如通过第三方登录)的应用需要:
- 在多个浏览器中测试这些方案。
- 应用支持旧版浏览器中讨论的 Cookie 策略浏览器探查缓解措施。
有关测试和浏览器探查说明,请参阅下一部分。
使用可选择采用新行为的客户端版本测试 Web 应用。 Chrome、Firefox 和 Microsoft Edge Chromium 都具有可用于测试的新的“选择加入”功能标志。 在应用修补程序(特别是 Safari)后,验证应用是否与较旧的客户端版本兼容。 有关详细信息,请参阅支持旧版浏览器。
Chrome 78 及更高版本生成误导性的测试结果。 这些版本具有临时缓解措施,允许 Cookie 的使用时间小于两分钟。 启用合适的测试标志后,Chrome 76 和 77 会生成更准确的结果。 要测试新行为,请将 chrome://flags/#same-site-by-default-cookies
切换为“已启用”。 据报告,Chrome 75 及更早版本使用新的 None
设置时失败。 有关详细信息,请参阅支持旧版浏览器。
Google 不提供较旧的 Chrome 版本。 但是,你可下载较旧版本的 Chromium,这将足以用于测试。 按照下载 Chromium 的说明进行操作。
Safari 12 严格执行了先前的草案,如果它在 Cookie 中检测到新的 None
值,则将失败。 必须通过支持旧版浏览器中所示的浏览器探查代码来避免这种情况。 请确保使用 Microsoft 身份验证库 (MSAL)、Active Directory 身份验证库 (ADAL) 或所使用的任何库来测试 Safari 12 和 13 以及基于 WebKit 的 OS 样式的登录。 问题取决于基础 OS 版本。 已知 OSX Mojave 10.14 和 iOS 12 存在与新行为相关的兼容性问题。 升级到 OSX Catalina 10.15 或 iOS 13 会解决此问题。 Safari 当前没有用于测试新规范行为的选择加入标志。
通过在具有功能标志 network.cookie.sameSite.laxByDefault
的 about:config
页面上选择加入,可在版本 68 及更高版本上测试 Firefox 对新标准的支持。 Firefox 旧版本未报告兼容性问题。
虽然 Microsoft Edge 支持旧的 SameSite
标准,但从版本 44 开始,它与新标准不存在任何兼容性问题。
功能标志为 edge://flags/#same-site-by-default-cookies
。 使用 Microsoft Edge Chromium 78 进行测试时,未发现兼容性问题。
Electron 的版本包括较早版本的 Chromium。 例如,Microsoft Teams 使用的 Electron 版本为 Chromium 66,该版本呈现了较旧的行为。 使用你的产品所用的 Electron 版本执行你自己的兼容性测试。 有关详细信息,请参阅支持旧版浏览器。
2016 SameSite
标准要求将未知值视为 SameSite=Strict
值。 因此,任何支持原始标准的旧版浏览器都可能在检测到 SameSite
属性具有 None
值时中断。 如果 Web 应用要支持这些旧版浏览器,它们必须实现浏览器探查。 ASP.NET Core 不会为你实现浏览器探查,因为 User-Agent
请求标头值非常不稳定,每周都会更改。 相反,Cookie 策略中的扩展点允许添加特定于 User-Agent
的逻辑。
在 Startup.cs 中,添加以下代码:
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 */)
{
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)
{
// Before UseAuthentication or anything else that writes cookies.
app.UseCookiePolicy();
app.UseAuthentication();
// code omitted for brevity
}
通过 Microsoft.AspNetCore.SuppressSameSiteNone
兼容性开关,可暂时选择退出新的 ASP.NET Core Cookie 行为。 将以下 JSON 添加到项目的 runtimeconfig.template.json 文件中:
{
"configProperties": {
"Microsoft.AspNetCore.SuppressSameSiteNone": "true"
}
}
下述项的相关 SameSite
修补程序即将发布:
- ASP.NET Core 2.1、2.2 和 3.0
Microsoft.Owin
4.1System.Web
(用于 .NET Framework 4.7.2 及更高版本)
ASP.NET
- Microsoft.AspNetCore.Builder.CookiePolicyOptions.MinimumSameSitePolicy
- Microsoft.AspNetCore.Http.CookieBuilder.SameSite
- Microsoft.AspNetCore.Http.CookieOptions.SameSite
- Microsoft.AspNetCore.Http.SameSiteMode
- Microsoft.Net.Http.Headers.SameSiteMode
- Microsoft.Net.Http.Headers.SetCookieHeaderValue.SameSite
从 .NET Core SDK 3.1.400 开始,RunResolvePackageDependencies
目标仅返回最上层包引用。
.NET Core SDK 3.1.400
在早期版本的 .NET Core SDK 中,RunResolvePackageDependencies
目标创建了以下 MSBuild 项,其中包含 NuGet 资产文件中的信息:
PackageDefinitions
PackageDependencies
TargetDefinitions
FileDefinitions
FileDependencies
Visual Studio 使用这些数据来填充解决方案资源管理器中的依赖项节点。 但这些数据可能很大,除非对依赖项节点进行了扩展,否则不需要这些数据。
从 .NET Core SDK 3.1.400 版开始,默认不会生成这些项中的大多数。 仅返回 Package
类型的项。 如果 Visual Studio 需要这些项来填充依赖项节点,它会直接从资产文件中读取信息。
引入此更改是为了改进 Visual Studio 内的解决方案加载性能。 之前系统会加载所有的包引用,包括加载多数用户永远不会查看的许多引用。
如果你有依赖于所创建项的 MSBuild 逻辑,请在项目文件中将 EmitLegacyAssetsFileItems
属性设置为 true
。 此设置会启用以前的行为(这种行为将创建所有项)。
MSBuild
不可用
从 .NET Core 3.1 开始,某些 Windows 窗体控件不再可用。
从 .NET Core 3.1 开始,各种 Windows 窗体控件不再可用。 .NET Framework 2.0 中引入改进了设计和支持的替换控件。 弃用的控件之前已从设计器工具箱中删除,但仍可供使用。
以下类型不再可用:
- ContextMenu
- DataGrid
- DataGrid.HitTestType
- DataGrid.HitTestInfo
- DataGridBoolColumn
- DataGridCell
- DataGridColumnStyle
- DataGridColumnStyle.DataGridColumnHeaderAccessibleObject
- DataGridColumnStyle.CompModSwitches
- DataGridLineStyle
- DataGridParentRowsLabelStyle
- DataGridPreferredColumnWidthTypeConverter
- DataGridTableStyle
- DataGridTextBox
- DataGridTextBoxColumn
- GridColumnStylesCollection
- GridTablesFactory
- GridTableStylesCollection
- IDataGridEditingService
- IMenuEditorService
- MainMenu
- Menu
- Menu.MenuItemCollection
- MenuItem
- ToolBar
- ToolBarAppearance
- ToolBarButton
- ToolBar.ToolBarButtonCollection
- ToolBarButtonClickEventArgs
- ToolBarButtonStyle
- ToolBarTextAlign
3.1
每个已删除的控件都有一个推荐的替换控件。 请参阅以下表:
已删除的控件 (API) | 推荐的替换控件 | 已删除的关联 API |
---|---|---|
ContextMenu | ContextMenuStrip | |
DataGrid | DataGridView | DataGridCell、DataGridRow、DataGridTableCollection、DataGridColumnCollection、DataGridTableStyle、DataGridColumnStyle、DataGridLineStyle、DataGridParentRowsLabel、DataGridParentRowsLabelStyle、DataGridBoolColumn、DataGridTextBox、GridColumnStylesCollection、GridTableStylesCollection、HitTestType |
MainMenu | MenuStrip | |
菜单 | ToolStripDropDown、ToolStripDropDownMenu | MenuItemCollection |
MenuItem | ToolStripMenuItem | |
ToolBar | ToolStrip | ToolBarAppearance |
ToolBarButton | ToolStripButton | ToolBarButtonClickEventArgs、ToolBarButtonClickEventHandler、ToolBarButtonStyle、ToolBarTextAlign |
Windows 窗体
- System.Windows.Forms.ContextMenu
- System.Windows.Forms.GridColumnStylesCollection
- System.Windows.Forms.GridTablesFactory
- System.Windows.Forms.GridTableStylesCollection
- System.Windows.Forms.IDataGridEditingService
- System.Windows.Forms.MainMenu
- System.Windows.Forms.Menu
- System.Windows.Forms.Menu.MenuItemCollection
- System.Windows.Forms.MenuItem
- System.Windows.Forms.ToolBar
- System.Windows.Forms.ToolBar.ToolBarButtonCollection
- System.Windows.Forms.ToolBarAppearance
- System.Windows.Forms.ToolBarButton
- System.Windows.Forms.ToolBarButtonClickEventArgs
- System.Windows.Forms.ToolBarButtonStyle
- System.Windows.Forms.ToolBarTextAlign
- System.Windows.Forms.DataGrid
- System.Windows.Forms.DataGrid.HitTestType
- System.Windows.Forms.DataGridBoolColumn
- System.Windows.Forms.DataGridCell
- System.Windows.Forms.DataGridColumnStyle
- System.Windows.Forms.DataGridLineStyle
- System.Windows.Forms.DataGridParentRowsLabelStyle
- System.Windows.Forms.DataGridPreferredColumnWidthTypeConverter
- System.Windows.Forms.DataGridTableStyle
- System.Windows.Forms.DataGridTextBox
- System.Windows.Forms.DataGridTextBoxColumn
- System.Windows.Forms.Design.IMenuEditorService
现在,当鼠标悬停和通过键盘选择时,DataGridView 将显示单元格的文本和错误工具提示。 如果显示工具提示,则不会引发 DataGridView.CellFormatting 事件。
在 .NET Core 3.1 之前,将 ShowCellToolTips 属性设置为 true
的 DataGridView 会在鼠标悬停在单元格上方时显示单元格文本和错误的工具提示。 之前,通过键盘选择单元格时(例如通过使用 Tab 键、快捷键或箭头导航),不显示工具提示。 如果用户编辑了单元格,然后在 DataGridView 仍处于编辑模式时将鼠标悬停在未设置 ToolTipText 属性的单元格上,则会引发 CellFormatting 事件,对要在单元格中显示的单元格文本进行格式化。
为满足辅助功能标准,自 .NET Core 3.1 起,将 ShowCellToolTips 属性设置为 true
的 DataGridView 不仅在鼠标悬停在单元格上时会显示单元格文本和错误的工具提示,而且在通过键盘选择单元格时也会显示。 由于这一变更,如果鼠标在 DataGridView 处于编辑模式时悬停在未设置 ToolTipText 属性的单元格上,不会引发 CellFormatting 事件 。 不引发该事件的原因是鼠标悬停的单元格的内容显示为工具提示,而不是显示在单元格中。
3.1
当 DataGridView 处于编辑模式时,对依赖 CellFormatting 事件的所有代码进行重构。
Windows 窗体
无