PHP Soap ssl如何信任自签名证书

时间:2016-12-28 10:12:12

标签: php web-services ssl soap wsdl

我在php中使用soap创建一个客户端,用于.net中的web服务。 Web服务通过https运行,带有自签名证书,对于测试,我必须信任此证书而不安装它。

问题是我总是得到这个错误:

SOAP-ERROR:解析WSDL:无法从' https://winsystemsintl.com:54904/PSAService.svc?wsdl'加载:未能加载外部实体" https://winsystemsintl.com:54904/PSAService.svc?wsdl"。

这是我的代码:

$opts = [
        'ssl' => [
            // set some SSL/TLS specific options
            'verify_peer' => false,
            'verify_peer_name' => false,
            'allow_self_signed' => true
        ],
         'http'=>[
            'user_agent' => 'PHPSoapClient'
        ]
    ];

    // Initialize Soap Client
    $this->client = new SoapClient($this->wsdl, array('ssl_method' => SOAP_SSL_METHOD_SSLv3,'soap_version' => SOAP_1_2,  'location' => 'https://winsystemsintl.com:54904/PSAService.svc','stream_context' => stream_context_create($opts), 'exceptions' => true, 'trace' => true));

我能够使用wget获取wsd:

wget --secure-protocol = SSLv3 https://winsystemsintl.com:54904/PSAService.svc?wsdl --no-check-certificate

希望有人可以帮助我,非常感谢。

1 个答案:

答案 0 :(得分:1)

问题是PHP在下载WSDL文件时会忽略您的流上下文。解决方法是下载WSDL文件,并将所有架构导入到本地文件系统(我在这里使用tidy来打印XML):

wget --secure-protocol=SSLv3 https://winsystemsintl.com:54904/PSAService.svc?wsdl --no-check-certificate -O - | tidy -xml -indent > PSAService.svc?wsdl
wget --secure-protocol=SSLv3 https://winsystemsintl.com:54904/PSAService.svc?xsd=xsd0 --no-check-certificate -O - | tidy -xml -indent > PSAService.svc?xsd=xsd0
wget --secure-protocol=SSLv3 https://winsystemsintl.com:54904/PSAService.svc?xsd=xsd1 --no-check-certificate -O - | tidy -xml -indent > PSAService.svc?xsd=xsd1
wget --secure-protocol=SSLv3 https://winsystemsintl.com:54904/PSAService.svc?xsd=xsd2 --no-check-certificate -O - | tidy -xml -indent > PSAService.svc?xsd=xsd2
wget --secure-protocol=SSLv3 https://winsystemsintl.com:54904/PSAService.svc?xsd=xsd3 --no-check-certificate -O - | tidy -xml -indent > PSAService.svc?xsd=xsd3

接下来,您必须编辑PSAService.svc?wsdl(wget保存到的文件名)并将导入更改为指向本地系统而不是Web。在您喜欢的编辑器中使用替换所有功能,并将'https://winsystemsintl.com:54904/'替换为''

示例之前:

<wsdl:types>
  <xsd:schema targetNamespace="http://tempuri.org/Imports">
    <xsd:import schemaLocation="https://winsystemsintl.com:54904/PSAService.svc?xsd=xsd0"
  namespace="http://tempuri.org/" />
    <xsd:import schemaLocation="https://winsystemsintl.com:54904/PSAService.svc?xsd=xsd1"
  namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
    <xsd:import schemaLocation="https://winsystemsintl.com:54904/PSAService.svc?xsd=xsd2"
  namespace="http://schemas.datacontract.org/2004/07/PSA.Service.MessageObjects.Pregunta" />
    <xsd:import schemaLocation="https://winsystemsintl.com:54904/PSAService.svc?xsd=xsd3"
  namespace="http://schemas.datacontract.org/2004/07/PSA.Service.MessageObjects.Respuesta" />
  </xsd:schema>
</wsdl:types>

<强>后:

<wsdl:types>
  <xsd:schema targetNamespace="http://tempuri.org/Imports">
    <xsd:import schemaLocation="PSAService.svc?xsd=xsd0"
  namespace="http://tempuri.org/" />
    <xsd:import schemaLocation="PSAService.svc?xsd=xsd1"
  namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
    <xsd:import schemaLocation="PSAService.svc?xsd=xsd2"
  namespace="http://schemas.datacontract.org/2004/07/PSA.Service.MessageObjects.Pregunta" />
    <xsd:import schemaLocation="PSAService.svc?xsd=xsd3"
  namespace="http://schemas.datacontract.org/2004/07/PSA.Service.MessageObjects.Respuesta" />
  </xsd:schema>
</wsdl:types>

对每个下载的文件重复。

接下来,将代码更改为以下内容(我假设所有PHP / WSDL文件都在同一个文件夹中):

$opts = [
'ssl' => [
  // set some SSL/TLS specific options
  'verify_peer' => false,
  'verify_peer_name' => false,
  'allow_self_signed' => true
],
  'http'=>[
    'user_agent' => 'PHPSoapClient'
  ]
];

// Initialize Soap Client
$client = new SoapClient('PSAService.svc?wsdl', array('ssl_method' => SOAP_SSL_METHOD_SSLv3,'soap_version' => SOAP_1_2,  'location' => 'https://winsystemsintl.com:54904/PSAService.svc','stream_context' => stream_context_create($opts), 'exceptions' => true, 'trace' => true));
var_dump($client->__getFunctions());

现在SoapClient已跳过从网上下载WSDL,您已准备好开始使用您的信息流上下文进行通话。