0

我正在尝试从 HTTPS 服务器获取 WSDL 的内容

<?php
echo file_get_contents("https://zendsoap.lan/Zend_Soap_Server.php?wsdl");
?>

它返回:

警告:file_get_contents() [function.file-get-contents]:SSL 操作失败,代码为 1。OpenSSL 错误消息:错误:1408E0F4:SSL 例程:func(142):reason(244) in /Applications/AMPPS/www/ zendSoap.lan/Zend_Soap_Client.php 在第 4 行

警告:file_get_contents() [function.file-get-contents]:无法在第 4 行的 /Applications/AMPPS/www/zendSoap.lan/Zend_Soap_Client.php 中启用加密

警告:file_get_contents(https://zendsoap.lan/Zend_Soap_Server.php?wsdl) [function.file-get-contents]:无法打开流:/Applications/AMPPS/www/zendSoap.lan/Zend_Soap_Client.php 中的操作失败在第 4 行

并且当我可以转到 WSDL 位置 (https://zendsoap.lan/Zend_Soap_Server.php?wsdl) 时:一切看起来都很好。

PS:谁能告诉我如何共享 WSDL 文件

4

3 回答 3

4

我同意 RockyFord 关于这是一个 SSL 问题的观点(我很确定您将拥有一个自签名证书,并且由于使用 SSL,您需要采取一些步骤来最大程度地减少安全问题)。关于眼前的问题,您可以尝试使用类似以下的代码来修复它:

$url = 'https://zendsoap.lan/Zend_Soap_Server.php?wsdl';

$contextOptions = array(
    'ssl' => array(
        'verify_peer' => true,
        'CN_match'    => 'zendsoap.lan' // assuming zendsoap.lan is the CN used in the certificate
    )
);

$sslContext = stream_context_create($contextOptions);

$wsdlContent = file_get_contents($url, NULL, $sslContext);

更新: 将上面的代码更改为

 'verify_peer' => false

虽然它对于基本开发来说可能没问题,但这并不是一个好主意,绝对不应该在生产环境中使用,因为它会引入严重的安全问题 - 请参阅这篇关于如何从 PHP 代码中通过 SSL 正确保护远程 API 调用的优秀文章Artur Ejsmont了解有关此主题的更多信息以及OWASP的传输层安全备忘单保护 Web 服务

要了解关于在 Zend Framework 应用程序中共享 WSDL 的观点,您可以执行以下操作来开始:

// go to application/configs/application.ini
// if your APPLICATION_ENV is development then add the following line in the development section:
phpSettings.soap.wsdl_cache_enabled = 0

上面的行将防止您的 wsdl 在开发过程中被缓存。接下来,您可能想要创建一个 SoapController 并添加此操作,如下所示:

public function serverAction()
{
    $baseUrl = 'http://zendsoap.lan/soap/server';

    if( isset( $_GET['wdsl'] ) ) {
        $strategy = new Zend_Soap_Wsdl_Strategy_AnyType();
        $server = new Zend_Soap_AutoDiscover($strategy);
        $server->setUri($baseUrl);
        $server->setClass('Application_Model_Web_Service');
        $server->handle();
    } else {            
        $server = new Zend_Soap_Server($baseUrl . '?wsdl');
        $server->setClass('Application_Model_Web_Service');
        $server->handle();
    }
}

上述方法的好处是 WSDL 将为您即时生成。您会注意到 setClass() 方法将被调用,并且将“Application_Model_Web_Service”作为唯一参数传递。要测试您的配置,我建议您创建该类并插入下面的方法。使用包含单一方法的简单服务测试您的配置将帮助您在使服务变得更复杂之前进行故障排除。这是示例方法:

// Note: you should definitely comment your methods correctly in the class so 
// the WSDL will be generated correctly - by that I mean use @param and @return
// so the correct input and output types can be determined and added to the WSDL
// when the the ZF component generates it for you
/**     
 * @return string
 */
 public function getMessage()
 {
     return 'ok';
 }

更新: 同样针对您提出的关于使用Zend_Soap_Client访问 Web 服务的问题,因为看起来您打算使其成为安全服务,我建议您提出一个关于设置安全肥皂服务的单独问题php. 如果您在该问题中解释更多有关您尝试做什么的信息,您可能会从一系列专家那里获得有关最佳实践的一些很好的意见:-)

)

我知道您是 SO 的新手,所以如果您对答案感到满意,您可以接受它,通常最好只回复一个答案,而不是添加另一个答案来回复。当你知道当然很容易,当有人告诉你时更容易;-)

于 2013-01-16T15:28:56.890 回答
0

我尝试了您定义 Soap 服务器的方式,唯一的事情是我使用了我的自定义类而不是使用 Application_Model_Web_Service。我正在为客户端和服务器使用单个文件。当我在没有 ?wsdl 的情况下运行https://zendsoap.lan/Zend_Soap_Server.php时,结果如下:

<SOAP-ENV:Envelope>
 <SOAP-ENV:Body>
  <SOAP-ENV:Fault>
   <faultcode>WSDL</faultcode>
  <faultstring>SOAP-ERROR: Parsing WSDL: Couldn't load from 'https://zendsoap.lan/Zend_Soap_Server.php?wsdl' : failed to load external entity "https://zendsoap.lan/Zend_Soap_Server.php?wsdl"
  </faultstring>
  </SOAP-ENV:Fault>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

当我按照你所说的方式尝试 file_get_contents() 时,我得到了这个:

Warning: file_get_contents() [function.file-get-contents]: SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:func(144):reason(134) in /Applications/AMPPS/www/zendSoap.lan/https_soap_test.php on line 16

Warning: file_get_contents() [function.file-get-contents]: Failed to enable crypto in /Applications/AMPPS/www/zendSoap.lan/https_soap_test.php on line 16

Warning: file_get_contents(https://zendsoap.lan/Zend_Soap_Server.php?wsdl) [function.file-get-contents]: failed to open stream: operation failed in /Applications/AMPPS/www/zendSoap.lan/https_soap_test.php on line 16

这是我的证书截图的链接:http: //i.stack.imgur.com/bKoVD.png

非常感谢您的帮助。

于 2013-01-17T19:17:30.967 回答
0

通过更改 'verify_peer' => false 解决了问题

如果我在没有 file_get_contents() 的情况下使用 Zend_Soap_Client,您能否 (@dkcwd) 告诉我应该是什么代码。我的意思是有什么我在互联网上找不到的选项来做类似于'verify_peer' => false 的事情。

非常感谢@dkcwd

更新:让我总结一下我到底在做什么,我正在尝试通过 SSL 创建一个基本的 SOAP 服务器。在我的生产网站上提供 Web 服务之前,我必须在具有自签名证书的开发系统上对其进行测试(现在谁的身份验证是一个问题)。以下是我在这方面面临的问题:

  1. 当我尝试调用https://zendsoap.lan/Zend_Soap_server.php?wsdl时,它工作正常,我可以查看 wsdl。
  2. 但是当我尝试https://zendsoap.lan/Zend_Soap_server.php时,我得到了这个:

    SOAP-ERROR: Parsing WSDL: could't load from 'https://zendsoap.lan/Zend_Soap_Server.php?wsdl' : failed to load external entity "https://zendsoap.lan/Zend_Soap_Server.php?wsdl" 是吗我应该是的东西

  3. 我在开发服务器上运行 verify_peer=>false 的原因是不需要验证我自己创建的证书,但显然在生产中我希望验证证书。

这个东西在 NuSoap 上工作得很好,但是 NuSoap 中的大部分东西对于我们运行 PHP 5.4.6 的服务器来说已经被弃用了,所以对我来说使用 PHP 的 SOAP 扩展是最可靠的解决方案。我使用Zend的原因是我们正在将我们的系统从某个第三方框架迁移到 Zend 框架,并且每天我都会收到来自客户端的请求以添加这个和那个新组件,我假设如果我开发来自客户端的每个新请求使用 Zend 库之后,我很容易在后期迁移到 Zend 框架。

我希望我在那里有所了解。

提前谢谢了...

于 2013-01-17T19:53:48.977 回答