iOS/macOS 的 HttpClient 和 SSL/TLS 实现选择器

Xamarin.iOS、Xamarin.tvOS 和 Xamarin.Mac 的 HttpClient 实现选择器控制要使用的 HttpClient 实现。 可以切换到使用 iOS、tvOS 或 macOS 本机传输(NSUrlSessionCFNetwork,具体取决于 OS)的实现。 优点是支持 TLS 1.2、二进制文件更小和下载速度更快;缺点是需要运行事件循环才能执行异步操作。

项目必须引用 System.Net.Http 程序集。

警告

2018 年 4 月 – 由于安全要求的提高(包括 PCI 合规性),主要云服务提供商和 Web 服务器预计将停止支持低于 1.2 的 TLS 版本。 在早期版本的 Visual Studio 中创建的 Xamarin 项目默认使用旧版 TLS。

为了确保应用继续与这些服务器和服务配合使用,应使用如下所示的 NSUrlSession 设置更新 Xamarin 项目,然后重新生成应用并将其重新部署到用户

选择 HttpClient 堆栈

调整应用正在使用的 HttpClient

  1. 在“解决方案资源管理器”中双击“项目名称”打开“项目选项”
  2. 切换到项目的“生成”设置(例如,Xamarin.iOS 应用的“iOS 生成”)
  3. 从“HttpClient 实现”下拉列表中,为 HttpClient 类型选择以下选项之一:“NSUrlSession”(推荐)、“CFNetwork”或“托管”

Choose HttpClient implementation from Managed, CFNetwork, or NSUrlSession

提示

对于 TLS 1.2 支持,建议使用 NSUrlSession 选项。

NSUrlSession

基于 NSURLSession 的处理程序基于 iOS 7 及更高版本中提供的本机 NSURLSession 框架。 这是建议的设置

优点

  • 它使用本机 API 提高性能并缩小可执行文件大小。
  • 支持最新标准,例如 TLS 1.2。

缺点

  • 需要 iOS 7 或更高版本。
  • 某些 HttpClient 功能/选项不可用。

CFNetwork

基于 CFNetwork 的处理程序基于 iOS 6 及更高版本中提供的本机 CFNetwork 框架。

优点

  • 它使用本机 API 提高性能并缩小可执行文件大小。
  • 支持较新的标准(如 TLS 1.2)。

缺点

  • 需要 iOS 6 或更高版本。
  • 在 watchOS 上不可用。
  • 某些 HttpClient 功能/选项不可用。

托管

托管处理程序是随早期版本的 Xamarin 一起提供的完全托管的 HttpClient 处理程序。

优点

  • 它具有与 Microsoft .NET 和旧版 Xamarin 最兼容的功能集。

缺点

  • 它未与 Apple OS 完全集成,并且仅限于 TLS 1.0。 它将来可能无法连接到安全的 Web 服务器或云服务。
  • 它在加密等方面通常比本机 API 慢得多。
  • 它需要更多的托管代码,从而创建更大的可分发应用。

以编程方式设置 HttpMessageHandler

除了上面所示的项目范围配置之外,还可以通过构造函数实例化 HttpClient 和注入所需的 HttpMessageHandler 配置,如以下代码片段所示:

// This will use the default message handler for the application; as
// set in the Project Options for the project.
HttpClient client = new HttpClient();

// This will create an HttpClient that explicitly uses the CFNetworkHandler
HttpClient client = new HttpClient(new CFNetworkHandler());

// This will create an HttpClient that explicitly uses NSUrlSessionHandler
HttpClient client = new HttpClient(new NSUrlSessionHandler());

这样就可以使用与“项目选项”对话框中声明的内容不同的 HttpMessageHandler

SSL/TLS 实现

SSL(安全套接字层)及其后继者 TLS(传输层安全性)通过 System.Net.Security.SslStream 提供对 HTTP 和其他网络连接的支持。 Xamarin.iOS、Xamarin.tvOS 或 Xamarin.Mac 的 System.Net.Security.SslStream 实现将调用 Apple 的本机 SSL/TLS 实现,而不是使用 Mono 提供的托管实现。 Apple 的本机实现支持 TLS 1.2。

警告

即将发布的 Xamarin.Mac 4.8 版本仅支持 macOS 10.9 或更高版本。 早期版本的 Xamarin.Mac 支持 macOS 10.7 或更高版本,但这些较旧的 macOS 版本缺少足够的 TLS 基础结构,无法支持 TLS 1.2。 若要面向 macOS 10.7 或 macOS 10.8,请使用 Xamarin.Mac 4.6 或更早版本。

应用传输安全性

Apple 的应用传输安全性 (ATS) 会强制实现 Internet 资源(例如应用的后端服务器)与应用之间的安全连接。 ATS 可确保所有 Internet 通信都符合安全连接最佳做法,从而防止直接通过应用或其正在使用的库意外泄露敏感信息。

由于为 iOS 9、tvOS 9 和 OS X 10.11 (El Capitan) 及更高版本生成的应用中默认启用了 ATS,因此使用 NSUrlConnectionCFUrlNSUrlSession 的所有连接都受 ATS 安全要求的约束。 如果连接不符合这些要求,它们将失败并出现异常。

根据 HttpClient 堆栈和 SSL/TLS 实现选择,可能需要对应用进行修改才能正确使用 ATS。

有关 ATS 的详细信息,请参阅我们的 App 传输安全指南。

已知问题

本部分介绍 Xamarin.iOS 中 TLS 支持的已知问题。

项目加载失败,出现错误“找不到请求的值 AppleTLS”

Xamarin.iOS 9.8 引入了一些新设置,其中包含 Xamarin.iOS 应用程序的 .csproj 文件。 当使用旧版 Xamarin.iOS 打开项目时,这些更改可能会导致问题。 以下屏幕截图是在此方案中可能显示的错误消息示例:

Screenshot of error while trying to load project, requested value legacy not found

此错误是由 Xamarin.iOS 9.8 中的项目文件引入 MtouchTlsProvider 设置引起的。 如果无法更新到 Xamarin.iOS 9.8(或更高版本),解决方法是手动编辑 .csproj 文件应用程序,移除 MtouchTlsprovider 元素,然后保存更改后的项目文件

以下代码片段是 .csproj 文件中 MtouchTlsProvider 设置的示例:

<MtouchTlsProvider>Default</MtouchTlsProvider>