如何在iOS 9中启用App Transport Security加载HTTP URL?

时间:2015-06-09 12:15:10

标签: ios url nsurl ios9 app-transport-security

因此,昨晚发布的iOS新测试版SDK具有“App Transport Security”,鼓励开发人员使用https而不是http。原则上,这是一个好主意,我已经在我们的临时/生产环境中使用https。但是,当iOS应用程序连接到我在笔记本电脑上运行的Web服务时,我在本地开发环境中没有设置https。

从今天早上的一些游戏中可以看出,即使您提交了一个http网址,URL加载系统也会决定使用https。有谁知道如何禁用此行为 - 即使只是针对特定的URL?

8 个答案:

答案 0 :(得分:661)

有关详细信息,请参阅Apple的Info.plist reference(感谢@ gnasher729)。

您可以在Info.plist中添加特定域的例外:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>testdomain.com</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSExceptionRequiresForwardSecrecy</key>
            <true/>
            <key>NSExceptionMinimumTLSVersion</key>
            <string>TLSv1.2</string>
            <key>NSThirdPartyExceptionAllowsInsecureHTTPLoads</key>
            <false/>
            <key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
            <true/>
            <key>NSThirdPartyExceptionMinimumTLSVersion</key>
            <string>TLSv1.2</string>
            <key>NSRequiresCertificateTransparency</key>
            <false/>
        </dict>
    </dict>
</dict>

每个例外域的所有密钥都是可选的。发言者没有详细说明任何一个键,但我认为它们都非常明显。

(来源:WWDC 2015 session 703, “Privacy and Your App”,30:18)

如果您的应用有充分的理由,您还可以使用单个密钥忽略所有应用传输安全限制:

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

如果您的应用没有充分的理由,您可能会有被拒绝的风险:

  

将NSAllowsArbitraryLoads设置为true将允许它工作,但Apple非常清楚他们打算拒绝使用此标志的应用程序而没有特定原因。使用NSAllowsArbitraryLoads的主要原因我可以想到的是用户创建的内容(链接共享,自定义Web浏览器等)。在这种情况下,Apple仍然希望您包含对您控制的URL强制执行A​​TS的例外。

     

如果确实需要访问未通过TLS 1.2提供的特定URL,则需要为这些域编写特定的例外,而不是使用设置为yes的NSAllowsArbitraryLoads。您可以在NSURLSesssion WWDC会话中找到更多信息。

     

请小心分享NSAllowsArbitraryLoads解决方案。这不是Apple的推荐修复。

- kcharwood(感谢@ marco-tolman)

答案 1 :(得分:101)

由于已接受的答案提供了必要的信息,以及有关使用和disabling App Transport Security one can find more on this的更多信息。

对于每个域例外,请将这些添加到 Info.plist

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSExceptionDomains</key>
  <dict>
    <key>yourserver.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>

但如果我不知道我需要使用的所有不安全域,该怎么办? Info.plist

中使用以下键
<key>NSAppTransportSecurity</key>
<dict>
  <!--Include to allow all connections (DANGER)-->
  <key>NSAllowsArbitraryLoads</key>
      <true/>
</dict>

For more detail you can get from this link.

答案 2 :(得分:54)

关注this

我已经通过在info.plist中添加一些密钥解决了这个问题。 我遵循的步骤是:

  1. 打开我的项目info.plist文件

  2. 添加了一个名为NSAppTransportSecurity的密钥作为Dictionary

  3. 添加了一个名为NSAllowsArbitraryLoads的子密钥Boolean,并将其值设置为YES,如下图所示。 enter image description here
  4. 清理项目,现在一切正常,就像以前一样。

    参考Link

答案 3 :(得分:30)

如果您只想为本地开发服务器禁用应用传输策略,则以下解决方案可以正常运行。当您无法或无法设置HTTPS时(例如,在使用Google App Engine开发服务器时),此功能非常有用。

正如其他人所说,对于生产应用程序,绝对不能关闭ATP。

1)使用不同的plist进行Debug

复制Plist文件和NSAllowsArbitraryLoads。使用此Plist进行调试。

XCode Debug

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

2)排除本地服务器

或者,您可以使用单个plist文件并排除特定服务器。但是,it doesn't look like you can exclude IP 4 addresses因此您可能需要使用服务器名称(可在系统偏好设置 - &gt;共享中找到,或在本地DNS中配置)。

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>server.local</key>
        <dict/>
        <key>NSExceptionAllowsInsecureHTTPLoads</key>
        <true/>
    </dict>
</dict>

答案 4 :(得分:28)

我已解决为plist文件。

  1. 添加NSAppTransportSecurity:Dictionary。
  2. 添加名为&#34的子项; NSAllowsArbitraryLoads&#34; as Boolean:是
  3. enter image description here

答案 5 :(得分:20)

上面的配置对我不起作用。我尝试了很多键组合,这个工作正常:

enter image description here

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>mydomain.com</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSExceptionRequiresForwardSecrecy</key>
            <false/>
        </dict>
    </dict>
</dict>

答案 6 :(得分:16)

编译@adurdin和@User

给出的答案

将以下内容添加到您的info.plist&amp;使用相应的域名更改localhost.com,您也可以添加多个域:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
    <key>NSExceptionDomains</key>
    <dict>
        <key>localhost.com</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <false/>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <false/>
            <key>NSExceptionRequiresForwardSecrecy</key>
            <true/>
            <key>NSExceptionMinimumTLSVersion</key>
            <string>TLSv1.2</string>
            <key>NSThirdPartyExceptionAllowsInsecureHTTPLoads</key>
            <false/>
            <key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
            <true/>
            <key>NSThirdPartyExceptionMinimumTLSVersion</key>
            <string>TLSv1.2</string>
            <key>NSRequiresCertificateTransparency</key>
            <false/>
        </dict>
    </dict>
</dict>
</plist>

你的info.plist必须如下所示:

enter image description here

答案 7 :(得分:13)

这对我有用:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <false/>
    <key>NSExceptionDomains</key>
    <dict>
        <key><!-- your_remote_server.com / localhost --></key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSExceptionRequiresForwardSecrecy</key>
            <true/>
        </dict>
    <!-- add more domain here -->
    </dict>
</dict>

我只是想添加它来帮助别人并节省一些时间:

如果您使用的是:CFStreamCreatePairWithSocketToHost。确保您的host.plist中的CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)/*from .plist*/, (unsigned int)port, &readStream, &writeStream); 相同,或者如果您有套接字的单独域名,请将其添加到那里。

AUI().use( 'aui-io-deprecated','aui-modal', function(A){

     Liferay.Util.openWindow(
         {
             dialog: {
             centered: true,
             resizable: false,
             destroyOnClose: true,
             cache: false,
             width: 600,
             height: 500,
             modal: true
            },

});

希望这有帮助。干杯。 :)