@hyperion

Как подключиться к wcf https сервису под iis из php?

Есть некий wcf сервис с самоподписанным сертификатом под iis, к которому я могу подключиться из C# приложения.
Много времени убил, но никак не получается подключиться из php:
<?php

	$opts = array(
		'ssl' => array(
						'allow_self_signed' => true,
						'verify_peer' => false
					),
					'http'=>array(
						'user_agent' => 'PHPSoapClient'
					)
	);

	$options = array(
					'userName' => "TestUser", 
					'password' => "123",
					'encoding' => 'UTF-8', 
					'verifypeer' => false, 
					'verifyhost' => false, 
					'soap_version' => SOAP_1_2, 
					'trace' => 1, 
					'exceptions' => 1, 
					"connection_timeout" => 180, 
					'encoding' => 'UTF-8',
					'stream_context' => stream_context_create($opts) 
					);			
	ini_set("soap.wsdl_cache_enabled", 0);					
	libxml_disable_entity_loader(false);
	ini_set('allow_url_fopen', 1);
	ini_set('default_socket_timeout', 1000);

	$soapClient = new SoapClient("https://localhost/CrmApiService.svc?wsdl", $options);
	
	var_dump($soapClient);
	$parameters = array("ModelTemplateSysName" => "1234");
	print_r($soapClient->__getFunctions());
	$retval = $soapClient->ModelTemplateCheckExist($parameters);
	//var_dump($retval);
?>


Ошибка
PHP Fatal error:  SOAP-ERROR: Parsing WSDL: Couldn't load from 'https://localhost/CrmApiService.svc?wsdl' : failed to load external entity "https://localhost/CrmApiService.svc?wsdl"
 in \Desktop\wcftest\index.php on line 32
PHP Fatal error:  Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Couldn't load from 'https://localhost/CrmApiService.svc?wsdl' : failed to load external entity "https://localhost/CrmApiService.svc?wsdl"
 in \Desktop\wcftest\index.php:32
Stack trace:
#0 \Desktop\wcftest\index.php(32): SoapClient->SoapClient('https://localho...', Array)
#1 {main}
  thrown in \Desktop\wcftest\index.php on line 32


Web.config:
<?xml version="1.0"?>
<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  
  <system.serviceModel>

    <services>
      
      
      <service name="ManAcc.CRM.WcfApiService.CrmApiService"
               behaviorConfiguration="AuthenticationBehavior">

        <endpoint address="" 
                  binding="basicHttpBinding" 
                  bindingConfiguration="UserNameBinding" 
                  contract="ManAcc.CRM.WcfApiService.ICrmApiService" />
        <endpoint address="mex" 
                  binding="mexHttpsBinding" 
                  contract="IMetadataExchange" />
      </service>
    </services>

    

    <bindings>      
      <basicHttpBinding>
        <binding name="UserNameBinding">
          <security mode="TransportWithMessageCredential">
            <message clientCredentialType="UserName"/>
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    
    <behaviors>
      <serviceBehaviors>
        <behavior name="AuthenticationBehavior">
          <serviceMetadata httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceCredentials>
            <!--<serviceCertificate findValue="05044b8b040bb0372f03d1e8dc256d5ef93d0205" storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint" />-->
            <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="ManAcc.CRM.WcfApiService.CustomUserNameValidator, ManAcc.CRM.WcfApiService" />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>

    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>

  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
  </system.webServer>

</configuration>


Работающий клиент C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ManAcc.CRM.TestClient.ServiceReference1;
using System;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Net;
using System.Security.Cryptography.X509Certificates;
 
namespace ManAcc.CRM.TestClient
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            System.Net.ServicePointManager.CertificatePolicy = new TrustAllCertificatePolicy();

            var binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportWithMessageCredential);
            var endpointAddress = new EndpointAddress(@"https://localhost/CrmApiService.svc");

            using (var service = new CrmApiServiceClient(binding, endpointAddress))
            {
                var loginCredentials = new ClientCredentials();
                loginCredentials.UserName.UserName = @"TestUser";
                loginCredentials.UserName.Password = @"123";

                var defaultCredentials = service.Endpoint.Behaviors.Find<ClientCredentials>();
                service.Endpoint.Behaviors.Remove(defaultCredentials); 
                service.Endpoint.Behaviors.Add(loginCredentials); 
                
                Console.WriteLine(service.ModelTemplateCheckExist("123"));
                Console.ReadLine(); 
            }


        }
    }

    public class TrustAllCertificatePolicy : ICertificatePolicy
    {
        public bool CheckValidationResult(ServicePoint sp,
         X509Certificate cert, WebRequest req, int problem)
        {
            return true;
        }
    }
}
  • Вопрос задан
  • 1223 просмотра
Решения вопроса 1
@hyperion Автор вопроса
Решить проблему помог параметр ssl 'verify_peer_name' => false.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы