仅为模拟器禁用应用程序传输安全性

Posted

技术标签:

【中文标题】仅为模拟器禁用应用程序传输安全性【英文标题】:Disable App Transport Security for Simulator only 【发布时间】:2017-09-01 14:32:58 【问题描述】:

如何仅当我在模拟器上运行我的应用程序时禁用应用程序传输安全性(同时在我的设备上运行我的应用程序时仍保持启用它,即使在调试模式下也是如此)?有没有办法使用 Swift 代码而不是修改 Info.plist 文件来禁用它?

我问是因为我已经配置了一些东西(通过下面的代码 sn-p),以便模拟器(通过 HTTP)连接到在 localhost 上运行的开发服务器,并且设备(通过 HTTPS)连接到生产服务器在云端运行。

#if arch(x86_64) || arch(i386) // simulator
let apiBaseURLString = "http://localhost:3000"
#else                          // device
let apiBaseURLString = "https://api.example.com"
#endif

理想情况下,我希望在模拟器上启用 App Transport Security,并让模拟器通过 HTTPS 连接到在 localhost 上运行的开发服务器。我有这个工作,但我刚刚更新了 Xcode,它坏了。

【问题讨论】:

您这样做的理由是什么?在模拟器与设备中运行时,您是否访问不同的 URL。否则,您现在最好添加任何适当的 ATS 例外,这样您就不会将问题推到设备测试时。我不相信有办法在运行时更改 Info.plist,因为它是捆绑包的一部分,并且捆绑包不应该被更改。我认为更简单的解决方案是使用它自己的 Info.plist 创建一个新的模拟器特定构建配置。 我认为您应该在我的回答中查看选项 2,特别是“NSAllowsLocalNetworking”。 好的。我将会。谢谢你。另外,我刚刚为我的问题添加了理想的解决方案。 我假设您的开发服务器 ssl 连接使用的是自签名证书?这些可能很棘手。我认为您最好的选择是将本地网络异常添加到您的 info.plist。或者想办法恢复到开发服务器的有效 ssl 连接。 是的,它使用的是自签名证书。我想我遵循了这个:github.com/seviu/ios-SSL-localhost。好的。谢谢你。 :-) 【参考方案1】:

我认为此代码应该可以访问 .plist 文件,根据此代码,您可以更改您需要的内容并为此设置条件。

Bundle.main.object(forInfoDictionaryKey: key_name)

更新

我在这里发图片,请关注:

在这里你可以得到值:

NSAllowsArbitraryLoads = 1;

通过这个你可以根据你的要求设置一个条件。

谢谢

【讨论】:

OP 要求在运行时更改值,而不是在运行时读取值。如果在模拟器中运行,他们希望禁用 ATS。 @wottle 是的,你是对的,我发布这个是为了绕过这种情况,他想要什么,他可以通过设置条件来实现,我认为我在这里做了一些不成熟的事情:P 无论如何,你的解释很好,顺便谢谢。 是的,很遗憾,ATS 执行无法在运行时修改,因此即使他们可以读取 Info.plist,也无法根据需要修改行为。 @wottle 我认为有可能,您可以更改 .plist 数据,不确定运行时间,但可以更改 ATS 有什么问题?它应该改变。 因为 Info.plist 是在编译时读取的,所以在运行时更改它不会影响 ATS 行为。此外,Info.plist 被复制到包中,该包已签名,因此无法在运行时更改。【参考方案2】:

App Transport Security 在编译时通过读取 Info.plist 进行配置。在运行时更改它实际上对 ATS 执行没有影响,即使您可以在运行时更改 Info.plist(you can't)。

我只能想到两个解决方案:

    模拟器构建配置 - 您可以创建两个版本的 Info.plist,其中一个完全禁用 ATS,另一个用于在设备上运行。然后,您可以创建特定的构建配置以在模拟器上运行。在您的构建设置中,选择禁用 ATS 的新 Info-Simulator.plist。这样做的缺点是您需要在模拟器上运行之前更改构建配置 - 它不会自动为模拟器和设备使用正确的构建配置。

    模拟器没有不同的 ATS 设置。配置 ATS 以处理模拟器和物理设备。 ATS 异常有许多选项应该适用于大多数情况。本地网络连接需要例外?查看NSAllowsLocalNetworking。在 webview 中需要更大的灵活性?试试NSAllowsArbitraryLoadsInWebContent

很遗憾,您可以在运行时检测到模拟器,但无法在运行时更改 ATS 行为。您需要找到另一种方法,或者重新评估您是否真的需要在模拟器和设备上进行不同的配置。

【讨论】:

谢谢。好主意!我对解决方案 2 有两个顾虑:1) 我能否使用模拟器在 iOS 9.0 上测试我的应用程序? 2) 在发布版本(安装在最终用户的设备上)启用NSAllowsLocalNetworking 的后果是什么? 1 可能不会。 iOS 10 中添加了本地网络异常。 2. 如果您的应用确实尝试连接到本地网络上的资源,它将不会强制执行 ATS 要求。由于您的生产应用程序不会这样做,因此不会产生任何影响。 老实说,您需要投入大量的工作和复杂性来有时对本地主机进行测试。如果是我,我会选择选项 1,并且只需要一个 Info.plist 来在我针对 localhost 运行时禁用所有 ATS。另一个在针对产品服务器进行测试时使 ATS 保持开启(无例外)。 好的。谢谢你。根据Apple: Developer: Guides and Sample Code: Information Property List Key Reference: Cocoa Keys: NSAppTransportSecurity: Availability of ATS for Remote and Local Connections 的说法:“尽管 ATS 未强制用于连接到本地主机,但 Apple 强烈建议对任何本地连接使用传输层安全性 (TLS),同时使用自签名证书来验证本地 IP 地址。” 我将(再次)弄清楚如何让模拟器通过 HTTPS 连接到在 localhost 上运行的开发服务器。

以上是关于仅为模拟器禁用应用程序传输安全性的主要内容,如果未能解决你的问题,请参考以下文章

如何禁用 TestFlight Beta 测试?

应用传输安全问题 iOS9

仅为授权配置弹簧安全性?

仅为生产环境禁用设计注册

Xcode 单元测试 - 仅为设备构建时出现链接错误

Chrome - 仅为本地主机禁用缓存?