SOAP请求在一个服务器上随机失败,但在iOS7上的另一个服务器上工作

时间:2013-10-07 09:46:45

标签: web-services soap ios6 ios7 sudzc

我有一个iPhone应用程序,它通过SOAP请求获取数据。 SOAP调用由sudzc.com库完成。

我必须向两台服务器发出SOAP请求。

  • 服务器A :是我自己的服务器,我在其中检索一些信息,我自己编写的SOAP响应
  • 服务器B :第三方服务器,它提供了一些必要的信息

iOS 6 该应用程序100%正确工作。

iOS 7

  • 服务器A :完美运作
  • 服务器B :SOAP请求随机失败。我得到以下内容 有时会出现错误消息:

    < SOAP-ENV:Envelope xmlns:SOAP-ENV =" http://schemas.xmlsoap.org/soap/envelope/"> < SOAP-ENV:页眉/> < SOAP-ENV:身体与GT; < SOAP-ENV:故障与GT; <的faultcode> SOAP-ENV:服务器 < faultstring xml:lang =" en">无法访问信封:无法从给定的源创建信封:;嵌套异常是com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl:无法从给定源创建信封::无法从给定源创建信封:: org.xml.sax.SAXParseException:前面文档中的标记根元素必须格式良好:根元素之前的文档中的标记必须格式正确。 < / faultstring> <细节/> < / SOAP-ENV:故障与GT; < / SOAP-ENV:身体与GT; < / SOAP-ENV:信封>

任何人都有一个想法,为什么这只发生在iOS7上以及如何摆脱它?

更新 可能与以下事实有关:一台服务器在https上运行而另一台服务器在http?

上运行

1 个答案:

答案 0 :(得分:1)

我已向iOS小组写过支持请求。这是他们回复的内容......事实上它与htpps有关...以防万一有人遇到同样的错误,这可能是原因:


我正在回答您关于为什么您的SOAP请求在iOS 7上失败的问题,但仅限于针对您的两台服务器之一的问题。你写道:

  

可能与以下事实有关:一台服务器正在运行https和   另一个在http?

上运行

事实证明你的理论是正确的。这里的问题是iOS 7包含了BEAST攻击的推荐对策。

http://en.wikipedia.org/wiki/Transport_Layer_Security#BEAST_attack

http://www.educatedguesswork.org/2011/11/rizzoduong_beast_countermeasur.html

https://www.imperialviolet.org/2012/01/15/beastfollowup.html

iOS在与TLS 1.0或更早版本的服务器(TLS 1.1及更高版本包含他们自己的针对此攻击的修复程序)进行协商时应用此对策,该服务器协商使用块密码(流密码不容易受到此攻击)。

查看您发送给我的测试应用程序的数据包跟踪,我可以看到它打开了与www.xxxx.xy:443的TLS 1.2连接。该服务器将连接降级为TLS 1.0,然后协商使用AES-128块密码(SSL_RSA_WITH_AES_128_CBC_SHA)。在那之后,我可以看到这种对策的明显迹象。

我通过在模拟器上运行您的测试应用程序(准确地再现了问题)确认了我的分析,然后使用调试器设置安全传输的内部状态(在iOS上实现TLS的子系统)以完全禁用此对策。在这样做时,我发现您应用中的第一个标签工作正常。

这种对策的一个众所周知的副作用是它会导致编写不良的HTTPS服务器出现问题。这是因为它将HTTP请求(通过TLS连接运行的请求)分解为块,并且必须对服务器进行编码以正确接收这些块并将它们连接到单个HTTP请求中。有些服务器没有正确执行,导致各种有趣的失败。

解决此问题的最佳方法是修复服务器。服务器应该能够处理以块为单位接收HTTP消息,以RFC 2616规定的方式检测HTTP消息边界。

http://www.ietf.org/rfc/rfc2616.txt

如果该修复程序在短期内难以实施,则只需升级服务器以支持TLS 1.2即可解决此问题。无论如何,这是一个好主意。

另一个不太好的想法是解决服务器配置以协商使用流密码。

如果您不控制服务器,我强烈建议您游说服务器操作员以解决此问题的服务器端修复。 iOS 7并不是唯一实现此解决方案的客户端;您可以在最新版本的Chrome,Firefox等中找到它。

如果无法进行服务器端修复,则客户端的选项不太理想:

o您可以使用HTTP替换HTTPS。显然这不是一件好事,它还要求服务器支持HTTP。此外,HTTP还有自己的一系列无趣的问题(各种中间盒,尤其是那些由移动运营商运营的中间盒,比如使用HTTP消息传播)。

o在最低级别,您可以通过kSSLSessionOptionSendOneByteRecord标志为请求的安全传输上下文禁用此对策(请参阅参考资料)。此标志不能直接用于更高级别的软件,尽管可以在CFSocketStream层使用它(因为该API为您提供了一种获取其正在使用的安全传输上下文的方法)。

重要信息:高级API NSURLSession和NSURLConnection不允许您访问安全传输上下文,也不提供对TLS这方面的任何控制。因此,没有办法禁用这种对策并继续使用那些漂亮的高级API。

o您可以在我们的TLS基础架构(最好是CFSocketStream)之上实现您自己的HTTP层。唉,这是一个痛苦的世界:HTTP比你想象的要复杂得多。

对不起,我没有更好的消息。