关于ios:传输安全性阻止了明文HTTP

Transport security has blocked a cleartext HTTP

根据以下错误消息,我需要在我的info.plist中设置什么才能启用HTTP模式?

Transport security has blocked a cleartext HTTP (http://) resource
load since it is insecure. Temporary exceptions can be configured via
your app's Info.plist file.

Xcode

假设我的域名是example.com


用途:

Enter image description here

您必须在.plist文件中的nsapTransportSafety字典下将nsallowsBitraryLoads键设置为yes。

Plist configuration


以下是可视化设置:

visual settings for NSAllowsArbitraryLoads in info.plist via Xcode GUI


看到论坛申请后的交通安全吗?.

在iOS 9和OSX 10.11中配置应用程序传输安全例外的页面。

例如,可以添加特定域,如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<key>NSAppTransportSecurity</key>
<dict>
  <key>NSExceptionDomains</key>
  <dict>
    <key>example.com</key>
    <dict>
      <!--Include to allow subdomains-->
      <key>NSIncludesSubdomains</key>
      <true/>
      <!--Include to allow HTTP requests-->
      <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
      <true/>
      <!--Include to specify minimum TLS version-->
      <key>NSTemporaryExceptionMinimumTLSVersion</key>
      <string>TLSv1.1</string>
    </dict>
  </dict>
</dict>

懒惰的选择是:

1
2
3
4
5
6
<key>NSAppTransportSecurity</key>
<dict>
  <!--Include to allow all connections (DANGER)-->
  <key>NSAllowsArbitraryLoads</key>
      <true/>
</dict>

注:

info.plist是一个XML文件,因此您可以将此代码或多或少地放在文件中的任何位置。


如果您使用xcode 8.0和swift 3.0或swift 2.2,甚至目标C:

Enter image description here

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
    <key>NSExceptionDomains</key>
    <dict>
        <key>example.com</key>
        <dict>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSIncludesSubdomains</key>
            <true/>
        </dict>
    </dict>
</dict>


这是在iOS 9 gm seed上测试和工作的-这是允许特定域使用http而不是https的配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<key>NSAppTransportSecurity</key>
<dict>
      <key>NSAllowsArbitraryLoads</key>
      <false/>
       <key>NSExceptionDomains</key>
       <dict>
            <key>example.com</key> <!--Include your domain at this line -->
            <dict>
                <key>NSIncludesSubdomains</key>
                <true/>
                <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
                <true/>
                <key>NSTemporaryExceptionMinimumTLSVersion</key>
                <string>TLSv1.1</string>
            </dict>
       </dict>
</dict>

NSAllowsArbitraryLoads必须是false,因为它不允许所有不安全的连接,但是例外列表允许连接到一些没有https的域。


这是一个快速的解决方法(但不推荐),可以将其添加到plist中:

1
2
3
4
5
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

这意味着(根据苹果的文件):

NSAllowsArbitraryLoads
A Boolean value used to disable App Transport Security for any domains not listed in the NSExceptionDomains dictionary. Listed domains use the settings specified for that domain.

The default value of NO requires the default App Transport Security behaviour for all connections.

我真的推荐链接:

  • 苹果的技术说明
  • WWDC 2015第706部分(安全和应用程序)将在1:50左右开始
  • WWDC 2015第711期(与NSURLSession联网)
  • 通过应用传输安全性发送应用程序的博客文章

这有助于我理解原因和所有含义。

下面的xml(在file info.plist中)将:

1
2
3
4
5
6
7
8
9
10
11
12
13
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <false/>
    <key>NSExceptionDomains</key>
    <dict>
        <key>PAGE_FOR_WHICH_SETTINGS_YOU_WANT_TO_OVERRIDE</key>
        <dict>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
    </dict>
</dict>

不允许对所有页面进行任意调用,但是对于PAGE_FOR_WHICH_SETTINGS_YOU_WANT_TO_OVERRIDE将允许该连接使用HTTP协议。

在上面的XML中,您可以添加:

1
2
<key>NSIncludesSubdomains</key>
<true/>

如果要允许指定地址的子域的不安全连接。

最好的方法是阻止所有的任意加载(设置为false),并添加异常以只允许我们知道的地址。

对于感兴趣的读者

2018更新:

苹果公司不建议关闭此电源-更多信息可在207届WWDC 2018大会上找到,更多关于安全的解释。

因历史原因和发展阶段而留下最初的答案


对于那些想要了解这件事发生原因的人来说,除了如何解决它之外,请阅读下面的内容。

随着iOS 9的引入,为了提高应用程序与Web服务之间连接的安全性,应用程序与其Web服务之间的安全连接必须遵循最佳实践。最佳实践行为由应用程序传输安全强制执行到:

  • 防止意外泄露,以及
  • 提供安全的默认行为。

如应用传输安全技术说明所述,当与您的Web服务通信时,应用传输安全现在具有以下要求和行为:

  • The server must support at least Transport Layer Security (TLS) protocol version 1.2.
  • Connection ciphers are limited to those that provide forward secrecy (see the list of ciphers below.)
  • Certificates must be signed using a SHA256 or better signature hash algorithm, with either a 2048 bit or greater RSA key or a 256 bit or
    greater Elliptic-Curve (ECC) key.
  • Invalid certificates result in a hard failure and no connection.

换句话说,您的Web服务请求应该:a.)使用HTTPS和b.)使用带有转发保密性的TLS v1.2进行加密。

但是,正如其他文章中提到的,您可以通过在应用程序的Info.plist中指定不安全的域来覆盖应用程序传输安全性中的这种新行为。

要覆盖,您需要将NSAppTransportSecurity>NSExceptionDomains字典属性添加到您的Info.plist中。接下来,您将把Web服务的域添加到NSExceptionDomains字典中。

例如,如果我想绕过主机www.yourwebservicehost.com上Web服务的应用程序传输安全行为,那么我将执行以下操作:

  • 在Xcode中打开应用程序。

  • 在项目导航器中找到Info.plist文件,然后"鼠标右键"单击该文件并选择"打开为>源代码"菜单选项。属性列表文件将显示在右窗格中。

  • 将以下属性块放入主属性字典(在第一个下)。

  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSExceptionDomains</key>
        <dict>
            <key>www.example.com</key>
            <dict>
                <key>NSExceptionAllowsInsecureHTTPLoads</key>
                <true/>
                <key>NSExceptionMinimumTLSVersion</key>
                <string>TLSv1.1</string>
                <key>NSIncludesSubdomains</key>
                <true/>
            </dict>
        </dict>
    </dict>

    如果您需要为其他域提供异常,那么您可以在NSExceptionDomains下添加另一个dictionary属性。

    要了解更多关于上面引用的键的信息,请阅读已经提到的Technote。


    我不喜欢直接编辑plist。您可以使用GUI轻松地将其添加到plist中:

    • 单击左侧导航器中的info.plist。
    • 现在更改主区域中的数据:

      • 在最后一行添加+
      • 输入组名:app transport security settings
      • 右键单击该组并选择Add Row
      • 输入允许任意加载
      • 将右侧的值设置为"是"。

    Example


    Apple Document 1

    Apple Document 2

    有两种解决方案:

    解决方案1:

  • Info.plist文件中,添加一个带有关键字'NSAppTransportSecurity的字典。
  • 在字典中添加键为'Allow Arbitrary Loads'的另一个元素
  • Plist结构如下图所示。

    Solution 1

    解决方案2:

  • Info.plist文件中,添加一个带有关键字'NSAppTransportSecurity的字典。
  • 在字典中添加另一个元素,键为"EDOCX1"(6)
  • 使用nsdictionary类型的键'MyDomainName.com'添加元素
  • 添加键"EDOCX1"〔8〕为Boolean类型的元素,值设置为YES
  • 添加键"EDOCX1"〔11〕为Boolean类型的元素,值设置为YES
  • Plist结构如下图所示。

    Solution 2

    解决方案2是首选方案,因为它只允许选定的域,而解决方案1允许所有不安全的HTTP连接。


    iOS 9.0或更高版本提供传输安全。尝试在应用程序中调用WS时可能会出现此警告:

    Application Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.

    将以下内容添加到info.plist将禁用ATS:

    1
    2
    3
    4
    <key>NSAppTransportSecurity</key>
    <dict>
         <key>NSAllowsArbitraryLoads</key><true/>
    </dict>


    开发实例

    下面是一个plist的屏幕截图,它保持了ats的完整性(=安全性),但允许通过http而不是https连接到本地主机。它在xcode 7.1.1中工作。

    Enter image description here


    转到你的info.plist

  • 在空白处单击鼠标右键,然后单击"添加行"
  • 将密钥名写为nsapptransportsafety,在它下面
  • 选择例外域,向此添加新项目
  • 写下你需要访问的域名
  • 将域类型从字符串更改为字典,添加新项
  • nstemporaryexceptionallowsinsecurehttploads,它将是一个具有真值的布尔值。Look at the picture to follow it correctly

  • 如本技术说明所述,确定可以自动执行哪些设置:

    1
    /usr/bin/nscurl --ats-diagnostics --verbose https://your-domain.com


    根据苹果公司的说法,通常禁用ATS会导致应用程序被拒绝,除非你有充分的理由这样做。即使这样,您也应该为可以安全访问的域添加异常。

    苹果有一个很好的工具,可以告诉你使用什么设置:在终端中,输入

    1
    /usr/bin/nscurl --ats-diagnostics --verbose https://www.example.com/whatever

    NSCURL将检查这个请求是否失败,然后尝试各种设置,并告诉您具体通过了哪个设置,以及要做什么。例如,对于我访问的某个第三方URL,此命令告诉我此字典通过:

    1
    2
    3
    4
    5
    6
    7
    {
        NSExceptionDomains = {
           "www.example.com" = {
                NSExceptionRequiresForwardSecrecy = false;
            };
        };
    }

    要区分您自己的站点和不受您控制的第三方站点,请使用密钥nshirdpartyException要求ForwardSecredity。


    注意:plist中的异常域应该是小写的。

    示例:您已在"设置"->"共享"下将您的计算机命名为"MyAwesomeMacBook";您的服务器(用于测试目的)正在MyAwesomeMacBook上运行。本地:3000,您的应用程序需要向http://myAwesomeMacBook.local:3000/files…,您的plist需要将"MyAwesomeMacBook.local"指定为例外域。

    ——

    您的info.plist将包含…

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <key>NSAppTransportSecurity</key>
    <dict>
      <key>NSExceptionDomains</key>
      <dict>
        <key>myawesomemacbook.local</key>
        <dict>
          <!--Include to allow subdomains-->
          <key>NSIncludesSubdomains</key>
          <true/>
          <!--Include to allow HTTP requests-->
          <key>NSExceptionAllowsInsecureHTTPLoads</key>
          <true/>
        </dict>
      </dict>
    </dict>

    2015-09-25(Xcode在2015-09-18更新后):

    我用了一种非懒惰的方法,但没用。以下是我的尝试。

    第一,

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSExceptionDomains</key>
        <dict>
            <key>www.xxx.yyy.zzz</key>
            <dict>
                <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
                <true/>
                <key>NSTemporaryExceptionMinimumTLSVersion</key>
                <string>TLSv1.1</string>
                <key>NSIncludesSubdomains</key>
                <true/>
            </dict>
        </dict>
    </dict>

    第二,

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSExceptionDomains</key>
        <dict>
            <key>www.xxx.yyy.zzz</key>
            <dict>
                <key>NSExceptionAllowsInsecureHTTPLoads</key>
                <true/>
                <key>NSExceptionMinimumTLSVersion</key>
                <string>TLSv1.1</string>
                <key>NSIncludesSubdomains</key>
                <true/>
            </dict>
        </dict>
    </dict>

    最后,我使用了懒惰的方法:

    1
    2
    3
    4
    5
    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>

    可能有点不安全,但我找不到其他解决方案。


    在swift 4和xocde 10中,将nsallowsarbitraryloads更改为允许任意加载。所以看起来是这样的:

    1
    2
    3
    4
    <key>App Transport Security Settings</key>
    <dict>
         <key>Allow Arbitrary Loads</key><true/>
    </dict>

    用途:

    PList Screenshot to understand better

    在具有类型dictionary的plist文件中添加一个新项nsAppTransportSafety,然后在boolean类型的dictionary中添加子项nsallowsArrayLoads,并设置bool值yes。这对我有用。


    也许值得一提的是如何到达那里…

    plist是main.storyboard或viewcontroller.swift下面的一个文件。

    当您第一次点击它时,它通常是一个表格格式,所以右键点击文件并‘打开为’源代码,然后将下面的代码添加到末尾,即:

    1
     <key>NSAppTransportSecurity</key><dict><key>NSAllowsArbitraryLoads</key><true/></dict>

    复制粘贴上面的代码

    1
    2
    "</dict>
    </plist>"

    就在最后。


    Xcode 7.1的更新,面临问题27.10.15:

    info.plist中的新值是"应用传输安全设置"。从此处开始,本词典应包含:

    • 允许任意加载=是
    • 例外域(在此处插入您的HTTP域)

    对于那些来这里试图找出为什么他们的wkwebview总是白色并且不加载任何内容的人(正如这里所描述的,我如何让wkwebview在swift和MacOS应用程序中工作):

    如果上面所有的火箭科学对你都不起作用,检查一下明显的:沙盒设置

    sandbox settings]

    作为Swift和Cocoa的新手,但在编程方面经验丰富,我花了大约20个小时来寻找这个解决方案。几十个Hipster iOS教程和苹果主题演讲中没有一个提到这个小复选框。


    使用NSExceptionDomains可能不会同时应用效果,因为目标站点可能从http上的外部域加载资源(例如js文件)。它也可以通过将这些外部域添加到NSExceptionDomains中来解决。

    要检查哪些资源无法加载,请尝试使用远程调试。以下是一个教程:http://geeklearning.io/apache-cordova-and-remote-debugging-on-ios/


    对于Cordova,如果要将其添加到ios.json中,请执行以下操作:

    1
    2
    3
    4
    5
    "NSAppTransportSecurity": [
       {
         "xml":"<dict><key>NSAllowsArbitraryLoads</key><true /></dict>"
       }
    ]

    它应该在:

    1
    2
    3
    4
    "*-Info.plist": {
      "parents": {
       }
    }


    正如许多人所指出的,这是iOS 9.0附带的一个功能问题。他们添加了一个叫做应用程序传输安全的东西,当它破坏了我的应用程序时,我也很恼火。

    您可以在.plist文件中的nsapTransportSafety字典下使用nsallowsBitraryLoads键将其绑定为yes,但最终需要重新编写构成URL的代码以形成https://前缀。

    苹果已经在iOS 9.0中重新编写了nsurlconnection类。你可以在nsurconnection上阅读。

    否则,在有时间实施正确的解决方案之前,您可能必须退出iOS 9.0。