我正在尝试从wsdl创建一个PHP客户端,它使用WCF服务。 我通过传递凭证(不需要pem认证)设法使用C#控制台应用程序来使用Web服务。
wsdl的url如下(它是一个测试环境):
https://extenavigator.ukho.gov.uk/serviceB2B/submitUKHOOrdering.svc?wsdl
所以如果有人想尝试创建一个肥皂客户端,请使用此wsdl。
"尝试使用缺少相关服务权限的帐户进行访问将导致对ProcessResult.Failure确认的响应以及添加到Messages属性的消息:服务[serviceName]不可用于用户[userId]" (来自提供者)。
因此,具有错误凭据的工作SOAP客户端应返回上述消息。
为了在php中创建一个soap客户端,我首先通过wsdl2phpgenerator创建了存根类。然后我将soap客户端实例化如下:
ini_set('max_execution_time', 480);
ini_set('default_socket_timeout', 400);
$orderServiceClient = new OrderingService(array('login' => DIST_B2B_USERNAME, 'password' => DIST_B2B_PASSWORD, "trace"=>1,
"exceptions"=>1, 'cache_wsdl' => WSDL_CACHE_MEMORY, 'soap_version' => SOAP_1_2, 'keep_alive' => false,
"connection_timeout" => 240, 'verifypeer' => false, 'verifyhost' => false, "ssl_method" => SOAP_SSL_METHOD_TLS));
其中OrderingService是扩展SOAP客户端类的存根类。
最后我调用了这样一个方法:
$getHoldingsRequest = new GetHoldingRequest(DIST_ID, 25555, ProductType::AVCSCharts); // set some params for the called method
$responce = $orderServiceClient->GetHoldings($getHoldingsRequest); // call the method
我得到的错误是:错误获取http标头
我在php.ini和apache conf文件中启用了ssl。我正在使用Windows PC。
我已阅读此帖:
Connecting to WS-Security protected Web Service with PHP
SoapFault exception: [HTTP] Error Fetching http headers
我发现问题在于必须自定义soap标头才能传递凭据("用户名和密码验证通过SSL")
我还尝试创建自定义soap标头:
class WsseAuthHeader extends SoapHeader
{
private $wss_ns = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd';
function __construct($user, $pass, $ns = null)
{
if ($ns)
{
$this->wss_ns = $ns;
}
$auth = new stdClass();
$auth->Username = new SoapVar($user, XSD_STRING, NULL, $this->wss_ns, NULL, $this->wss_ns);
$auth->Password = new SoapVar($pass, XSD_STRING, NULL, $this->wss_ns, NULL, $this->wss_ns);
$username_token = new stdClass();
$username_token->UsernameToken = new SoapVar($auth, SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'UsernameToken', $this->wss_ns);
$security_sv = new SoapVar(
new SoapVar($username_token, SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'UsernameToken', $this->wss_ns),
SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'Security', $this->wss_ns);
parent::__construct($this->wss_ns, 'Security', $security_sv, true);
}
}
和
$wsse_header = new WsseAuthHeader("xxxx", "xxxx");
$orderServiceClient = new OrderingService(array('trace' => true, 'exceptions' => true, 'cache_wsdl' => WSDL_CACHE_MEMORY,
'soap_version' => SOAP_1_2, 'keep_alive' => false, 'connection_timeout' => 240));
$orderServiceClient->__setSoapHeaders(array($wsse_header));
最后
$getHoldingsRequest = new GetHoldingRequest(DIST_ID, 25555, ProductType::AVCSCharts);
$getHoldingsRequest->setRequestId($GUID);
try {
$responce = $orderServiceClient->GetHoldings($getHoldingsRequest);
} catch (Exception $e) {
echo $e->getMessage();
}
echo "<pre>" . var_export($orderServiceClient->__getLastRequest(), TRUE) . "</pre>";
我明白了:
获取http标头时出错
NULL
我也尝试过上述帖子中提到的其他内容,但没有结果。
从上述帖子中:
&#34;但正如我上面所说:我认为需要更多关于WS-Security规范和给定服务架构的知识才能实现这一点。&#34;
所以如果有人有使用soap客户端的经验,并且能够为这个wsdl创建一个php客户端,这将是一个很好的帮助。
对于GUID,我使用了以下功能:
function getGUID(){
if (function_exists('com_create_guid')){
return com_create_guid();
}else{
mt_srand((double)microtime()*10000);//optional for php 4.2.0 and up.
$charid = strtoupper(md5(uniqid(rand(), true)));
$hyphen = chr(45);// "-"
$uuid = chr(123)// "{"
.substr($charid, 0, 8).$hyphen
.substr($charid, 8, 4).$hyphen
.substr($charid,12, 4).$hyphen
.substr($charid,16, 4).$hyphen
.substr($charid,20,12)
.chr(125);// "}"
return $uuid;
}
}
$GUID = getGUID();