Amadeus e-Power Web 服务 - SOAP 身份验证设置问题 headers
Amadeus e-Power Web Service - issues setting SOAP auth headers
我在为 Amadeus e-Power 服务设置 AuthenticationSoapHeader
时遇到问题。我正在使用 PHP 的内置 SoapClient。
WSDL: https://staging-ws.epower.amadeus.com/ws_usitcolours/EpowerService.asmx?WSDL
基本 class 我已经做了测试:
class AmadeusSoapClient
{
private $_client;
private $_config = [
'wsdl' => 'https://staging-ws.epower.amadeus.com/ws_usitcolours/EpowerService.asmx?WSDL',
'namespace' => 'https://epowerv5.amadeus.com.tr/WS',
'auth' => [
'username' => '...',
'password' => '...'
],
'debug' => true
];
// Construct
public function __construct()
{
// Client
$this->_client = new \SoapClient($this->_config['wsdl'], [
'trace' => $this->_config['debug']
]);
// Headers
$headers = [
// Auth
new \SoapHeader($this->_config['namespace'], 'AuthenticationSoapHeader', [
'WSUserName' => $this->_config['auth']['username'],
'WSPassword' => $this->_config['auth']['password']
]),
];
// Set headers
$this->_client->__setSoapHeaders($headers);
}
// Request: CurrencyConversion
public function currencyConversion($fromCurrency = 'BGN', $toCurrency = 'EUR', $amount = 1.00)
{
$method = 'CurrencyConversion';
$params = [
'OTA_CurrencyConversionRQ' => [
'_' => '',
'FromCurrency' => $fromCurrency,
'ToCurrency' => $toCurrency,
'Amount' => $amount,
],
];
try {
return $this->_client->__call($method, [$params]);
} catch (\Exception $e) {
// ...
}
}
}
示例用法:
$client = new \AmadeusSoapClient();
$client->currencyConversion();
收到错误:
stdClass Object
(
[OTA_CurrencyConversionRS] => stdClass Object
(
[Errors] => stdClass Object
(
[Error] => Array
(
[0] => stdClass Object
(
[_] =>
[Type] => EpowerInternalError
[ErrorCode] => EPW.0000
[ShortText] => User Name is required
[Code] => A001
[NodeList] => EPower
[BreakFlow] =>
)
[1] => stdClass Object
(
[_] =>
[Type] => EpowerInternalError
[ErrorCode] => EPW.0000
[ShortText] => Password is required
[Code] => A001
[NodeList] => EPower
[BreakFlow] =>
)
)
)
)
)
无论我用 __setSopHeaders
设置 headers 还是用 __call
方法传递它们,它们总是被忽略.. 任何其他如何设置的想法他们?
对不需要身份验证的方法的请求工作正常。
有趣的是,同一个请求对 Postman 有效,但对 PHP SoapClient 或 SoapUI 无效。
问题出在 PHP 的内置 SoapClient
和 Amadeus 的 .NET 服务器之间的 SSL 通信中。
无论如何,无法建立 SSL 连接,无论我如何设置(强制)Soap 使用 SSL 我总是收到 https connection must be used
错误。
遗憾的是,我没有更多的空闲时间来进一步调查,因此我决定改用 cURL。
这是我做的简单的class。希望对大家有帮助!
class AmadeusClient
{
private $_config = [
'wsdl' => 'https://staging-ws.epower.amadeus.com/ws_usitcolours/EpowerService.asmx?WSDL',
'namespace' => 'http://epowerv5.amadeus.com.tr/WS',
'auth' => [
'username' => '...',
'password' => '...'
],
'sessionCookieName' => 'ASP.NET_SessionId',
'debug' => true
];
public function testCall()
{
$fromCurrency = 'BGN';
$toCurrency = 'USD';
$amount = 15.00;
$result = $this->currencyConversionRequest($fromCurrency, $toCurrency, $amount);
echo '<pre>';
var_dump($result);
exit;
}
// Request: Currency conversion
public function currencyConversionRequest($fromCurrency = 'BGN', $toCurrency = 'EUR', $amount = 1.00)
{
$method = 'CurrencyConversion';
$params = [
'OTA_CurrencyConversionRQ' => [
'_attributes' => [
'FromCurrency' => $fromCurrency,
'ToCurrency' => $toCurrency,
'Amount' => $amount,
]
],
];
$result = $this->sendRequest($method, $params);
if (isset($result->Body->CurrencyConversionResponse->OTA_CurrencyConversionRS->Success)) {
$array = (array) $result->Body->CurrencyConversionResponse->OTA_CurrencyConversionRS->attributes();
if (!empty($array['@attributes'])) {
return $array['@attributes'];
}
}
return false;
}
public function sendRequest($method, $params)
{
$body = \Helpers\ArrayToXml::convert($params, [
'rootElementName' => $method,
'_attributes' => [
'xmlns' => $this->_config['namespace']
]
]);
$requestBody = '
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<AuthenticationSoapHeader xmlns="'. $this->_config['namespace'] .'">
<WSUserName>'. $this->_config['auth']['username'] .'</WSUserName>
<WSPassword>'. $this->_config['auth']['password'] .'</WSPassword>
</AuthenticationSoapHeader>
</soap:Header>
<soap:Body>
'. str_replace('<?xml version="1.0"?>', '', $body) .'
</soap:Body>
</soap:Envelope>
';
$headers = [
'Content-type: text/xml; charset=utf-8',
'Accept: text/xml',
'Cache-Control: no-cache',
'Pragma: no-cache',
'SOAPAction: '. $this->_config['namespace'] .'/'. $method,
'Content-length: '. mb_strlen($requestBody),
];
$ch = curl_init($this->_config['wsdl']);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, $requestBody);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$output = curl_exec($ch);
curl_close($ch);
$cleanXml = str_ireplace(['SOAP-ENV:', 'SOAP:'], '', $output);
return simplexml_load_string($cleanXml);
}
}
从 \Helpers\ArrayToXml 开始,它只是 Spatie 的一个简单的 class,将 PHP 数组转换为 XML。
资料来源:https://github.com/spatie/array-to-xml
上面生成的请求XMLclass:
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<AuthenticationSoapHeader xmlns="http://epowerv5.amadeus.com.tr/WS">
<WSUserName>...</WSUserName>
<WSPassword>...</WSPassword>
</AuthenticationSoapHeader>
</soap:Header>
<soap:Body>
<CurrencyConversion xmlns="http://epowerv5.amadeus.com.tr/WS">
<OTA_CurrencyConversionRQ FromCurrency="BGN" ToCurrency="USD" Amount="15"/>
</CurrencyConversion>
</soap:Body>
</soap:Envelope>
响应:
array(3) {
["Amount"]=>
string(4) "9.00"
["TruncatedAmount"]=>
string(4) "8.67"
["OtherChargesAmount"]=>
string(4) "8.67"
}
我在为 Amadeus e-Power 服务设置 AuthenticationSoapHeader
时遇到问题。我正在使用 PHP 的内置 SoapClient。
WSDL: https://staging-ws.epower.amadeus.com/ws_usitcolours/EpowerService.asmx?WSDL
基本 class 我已经做了测试:
class AmadeusSoapClient
{
private $_client;
private $_config = [
'wsdl' => 'https://staging-ws.epower.amadeus.com/ws_usitcolours/EpowerService.asmx?WSDL',
'namespace' => 'https://epowerv5.amadeus.com.tr/WS',
'auth' => [
'username' => '...',
'password' => '...'
],
'debug' => true
];
// Construct
public function __construct()
{
// Client
$this->_client = new \SoapClient($this->_config['wsdl'], [
'trace' => $this->_config['debug']
]);
// Headers
$headers = [
// Auth
new \SoapHeader($this->_config['namespace'], 'AuthenticationSoapHeader', [
'WSUserName' => $this->_config['auth']['username'],
'WSPassword' => $this->_config['auth']['password']
]),
];
// Set headers
$this->_client->__setSoapHeaders($headers);
}
// Request: CurrencyConversion
public function currencyConversion($fromCurrency = 'BGN', $toCurrency = 'EUR', $amount = 1.00)
{
$method = 'CurrencyConversion';
$params = [
'OTA_CurrencyConversionRQ' => [
'_' => '',
'FromCurrency' => $fromCurrency,
'ToCurrency' => $toCurrency,
'Amount' => $amount,
],
];
try {
return $this->_client->__call($method, [$params]);
} catch (\Exception $e) {
// ...
}
}
}
示例用法:
$client = new \AmadeusSoapClient();
$client->currencyConversion();
收到错误:
stdClass Object
(
[OTA_CurrencyConversionRS] => stdClass Object
(
[Errors] => stdClass Object
(
[Error] => Array
(
[0] => stdClass Object
(
[_] =>
[Type] => EpowerInternalError
[ErrorCode] => EPW.0000
[ShortText] => User Name is required
[Code] => A001
[NodeList] => EPower
[BreakFlow] =>
)
[1] => stdClass Object
(
[_] =>
[Type] => EpowerInternalError
[ErrorCode] => EPW.0000
[ShortText] => Password is required
[Code] => A001
[NodeList] => EPower
[BreakFlow] =>
)
)
)
)
)
无论我用 __setSopHeaders
设置 headers 还是用 __call
方法传递它们,它们总是被忽略.. 任何其他如何设置的想法他们?
对不需要身份验证的方法的请求工作正常。
有趣的是,同一个请求对 Postman 有效,但对 PHP SoapClient 或 SoapUI 无效。
问题出在 PHP 的内置 SoapClient
和 Amadeus 的 .NET 服务器之间的 SSL 通信中。
无论如何,无法建立 SSL 连接,无论我如何设置(强制)Soap 使用 SSL 我总是收到 https connection must be used
错误。
遗憾的是,我没有更多的空闲时间来进一步调查,因此我决定改用 cURL。 这是我做的简单的class。希望对大家有帮助!
class AmadeusClient
{
private $_config = [
'wsdl' => 'https://staging-ws.epower.amadeus.com/ws_usitcolours/EpowerService.asmx?WSDL',
'namespace' => 'http://epowerv5.amadeus.com.tr/WS',
'auth' => [
'username' => '...',
'password' => '...'
],
'sessionCookieName' => 'ASP.NET_SessionId',
'debug' => true
];
public function testCall()
{
$fromCurrency = 'BGN';
$toCurrency = 'USD';
$amount = 15.00;
$result = $this->currencyConversionRequest($fromCurrency, $toCurrency, $amount);
echo '<pre>';
var_dump($result);
exit;
}
// Request: Currency conversion
public function currencyConversionRequest($fromCurrency = 'BGN', $toCurrency = 'EUR', $amount = 1.00)
{
$method = 'CurrencyConversion';
$params = [
'OTA_CurrencyConversionRQ' => [
'_attributes' => [
'FromCurrency' => $fromCurrency,
'ToCurrency' => $toCurrency,
'Amount' => $amount,
]
],
];
$result = $this->sendRequest($method, $params);
if (isset($result->Body->CurrencyConversionResponse->OTA_CurrencyConversionRS->Success)) {
$array = (array) $result->Body->CurrencyConversionResponse->OTA_CurrencyConversionRS->attributes();
if (!empty($array['@attributes'])) {
return $array['@attributes'];
}
}
return false;
}
public function sendRequest($method, $params)
{
$body = \Helpers\ArrayToXml::convert($params, [
'rootElementName' => $method,
'_attributes' => [
'xmlns' => $this->_config['namespace']
]
]);
$requestBody = '
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<AuthenticationSoapHeader xmlns="'. $this->_config['namespace'] .'">
<WSUserName>'. $this->_config['auth']['username'] .'</WSUserName>
<WSPassword>'. $this->_config['auth']['password'] .'</WSPassword>
</AuthenticationSoapHeader>
</soap:Header>
<soap:Body>
'. str_replace('<?xml version="1.0"?>', '', $body) .'
</soap:Body>
</soap:Envelope>
';
$headers = [
'Content-type: text/xml; charset=utf-8',
'Accept: text/xml',
'Cache-Control: no-cache',
'Pragma: no-cache',
'SOAPAction: '. $this->_config['namespace'] .'/'. $method,
'Content-length: '. mb_strlen($requestBody),
];
$ch = curl_init($this->_config['wsdl']);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, $requestBody);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$output = curl_exec($ch);
curl_close($ch);
$cleanXml = str_ireplace(['SOAP-ENV:', 'SOAP:'], '', $output);
return simplexml_load_string($cleanXml);
}
}
从 \Helpers\ArrayToXml 开始,它只是 Spatie 的一个简单的 class,将 PHP 数组转换为 XML。 资料来源:https://github.com/spatie/array-to-xml
上面生成的请求XMLclass:
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<AuthenticationSoapHeader xmlns="http://epowerv5.amadeus.com.tr/WS">
<WSUserName>...</WSUserName>
<WSPassword>...</WSPassword>
</AuthenticationSoapHeader>
</soap:Header>
<soap:Body>
<CurrencyConversion xmlns="http://epowerv5.amadeus.com.tr/WS">
<OTA_CurrencyConversionRQ FromCurrency="BGN" ToCurrency="USD" Amount="15"/>
</CurrencyConversion>
</soap:Body>
</soap:Envelope>
响应:
array(3) {
["Amount"]=>
string(4) "9.00"
["TruncatedAmount"]=>
string(4) "8.67"
["OtherChargesAmount"]=>
string(4) "8.67"
}