Connecting to WS-Security protected Soap Web Service with PHP - soap

I have this wsdl file witch is not password protected and I need to call it via php soap client:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:afe4="http://gsis.ggps.interoperability/Afe4Interface">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken xmlns:wsse='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' >
<wsse:Username>****************************</wsse:Username>
<wsse:Password Type='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText'>*****************************</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
Other parameters here
</soapenv:Body>
</soapenv:Envelope>
I am trying to connect via php soapheader:
class WsseAuthHeader extends SoapHeader {
private $wss_ns = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-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($username, $password);
but it replies with
A security error was encountered when verifying the message
which according to the manual means wrong user or password.
Via postman I can connect.
Any suggestions?

It turned out that setting header to raw data solve the problem.
Thanks for your time!!!

Related

parsing soap response using Cypress

Facing issues while parsing this response using cypress,
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header/>
<soapenv:Body>
<p385:summaryOutputArray xmlns:p385="http://dataobject.simulation.com">
<p385:userName>MS</p385:userName>
</p385:summaryOutputArray>
</soapenv:Body>
</soapenv:Envelope>
Using Cypress How to read userName TAG? I can see in the log that whole xml is printed but can't get to the particular tag. Also, while using the function to get to the particular tag to get the value, I am getting null property
Firstly I used this. This is giving error. property reading null
const parser = new DOMParser();
const xmlDOM = parser.parseFromString(quoteResp, 'text/xml');
cy.log('xmlDOM ' + quoteResp.);
cy.wrap(Cypress.$(quoteResp)).then(quoteResp => {
const txt = quoteResp.filter('Body').find('p385:userName').text();
cy.log('value:' + txt);
});
Using this I can see the whole response in logs
then(quoteResp => {cy.log('xmlDOM ' + quoteResp.body);
It's not necessary to wrap the response, just query the xmlDOM like this
const xmlDOM = parser.parseFromString(quoteResp, 'application/xml');
const userName = xmlDOM.querySelector('userName').textContent
expect(userName).to.eq('MS')

Call soap web-service in mobilefirst hybrid app

I'm attempting to call SOAP Web-Service in hybrid app. How should I form SOAP message correctly if the back-end service displays the next error in log:
Caused by: com.ibm.websphere.security.WSSecurityException: Exception
org.apache.axis2.AxisFault: CWWSS7509W: The received SOAP request
message is rejected becasue it does not correctly specify SOAP action
and WS-Addressing action while there is at least one PolicySet
attachment at operation level of the
TestServiceService.TestServicePort service. ocurred while running
action:
com.ibm.ws.wssecurity.handler.WSSecurityConsumerHandler$1#9b5addf6 at
com.ibm.ws.security.context.ContextImpl.runWith(ContextImpl.java:394)
at
com.ibm.ws.wssecurity.platform.websphere.auth.WSSContextImpl.runWith(WSSContextImpl.java:65)
... 35 more
This is content of js file in adapter
function getToken(){
var token = WL.Server.getActiveUser().attributes.LtpaToken;
var fulltoken = "LtpaToken2=" + token;
return fulltoken;
}
function callService(){
WL.Logger.warn("INSIDE callService "+getToken());
var path="checkauth/TestServiceService";
var request=
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:q0="http://provider.ws/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<q0:callService />
</soapenv:Body>
</soapenv:Envelope>;
var input = {
method : 'post',
returnedContentType : 'xml',
path : path,
body: {
content: request.toString(),
contentType: 'text/xml; charset=utf-8',
},
headers: {"Cookie": getToken()}
};
var result= WL.Server.invokeHttp(input);
return result;
}
This is SOAP Envelope which was displayed via TCP/IP Monitor:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
<s:Security xmlns:s="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:w2="http://www.ibm.com/websphere/appserver/tokentype" soapenv:mustUnderstand="1">
<u:Timestamp>
<u:Created>2015-08-10T13:18:56.644Z</u:Created>
</u:Timestamp>
<s:BinarySecurityToken ValueType="w2:LTPAv2" u:Id="ltpa_20">dt8G5gZ9PpZ/Ea5oXr6EQd8dpmfXKiqeXiShPlpSWntK59hUzyoDNX9TKq1nFLfxUEJyJdjMxoG7EVxw8Q1zhyZdYhTXnsMkNVqScvSsPpX7ln/ad+/WAHqaaFymD8XtVEsjOlezQDarPaUmnKAQRUSrLkRnL5B1MoCclTe129Oojg8o+hACgDKjuvPnvL8jaf45wNiou6Il5ZOayBcoHpNehI7i2hADa4fTKzX/T69OPnsZOyWYrNosdezNd24b61vs85k2YK26rLTp5dkEp8f3mwKZBwOOK4z1wQdiAXJf6kQvzR22SfFitbJA5MStlBcovHAvB5T+J5Ip80/kI5BPa2ogoufd9HZAdKTNII8cHpHBN2Ub/+atzg1L7EhIWuzO1BPI62KoU/hPqAHn3uGCGrbIILesKx0TPvlgmU4Bg54H9prC0I8hgXbO1HLuz4M5DNE5ASFbH0W3LJ/UU7BGXJs6iJmfAfJtQ+ip5ZFHlLItZA+ca2LkVWmyD/xKVxyxHE1uDz8zV/CfV9Km0T+8FTA0Cfi/PIb5KiAagdrmqtw6GuJDbSCsC3sdh21G/cA3Y0p/f+rhDw8m/e17y1cEuq9HOBharwn7ET3wO30V4D4rGoLhd4QsN6X1z89gZmZVaI6J9urpPAEiSndmyQ==</s:BinarySecurityToken>
</s:Security>
<wsa:To>http://X.X.X.X:9082/checkauth/TestServiceService</wsa:To>
<wsa:MessageID>urn:uuid:5d1f8656-5550-40d2-9f39-c58f57279489</wsa:MessageID>
<wsa:Action>http://provider.ws/TestServiceDelegate/callServiceRequest</wsa:Action>
</soapenv:Header>
<soapenv:Body>
<ns2:callService xmlns:ns2="http://provider.ws/"/>
</soapenv:Body></soapenv:Envelope>
The body consists of a single line, and this makes the scenario a peculiar one, as well as raises a question is this is meant to work at all.
I can suggest two things:
You can attempt to parse your WSDL file with the SOAPUI application; it should show you how the SOAP envelope is supposed to look like
Use the Service Discovery feature in MobileFirst Studio that can generate the adapter for you with a ready SOAP envelope. Read more how to use this feature, here: http://www-01.ibm.com/support/knowledgecenter/SSHS8R_7.0.0/com.ibm.worklight.dev.doc/dev/c_using_service_discovery_wizard_to_explore_backend-services.html

How to set content-Type on WCF request

My issue is that a testing app like Google Postman (awesome tool, found here) can send the message.
When I send the message it's always refused (the exact same message) because nonse is 'expired'.
So there must be something different about how I'm sending it...
There is... Content-Type is different, for one... but not sure if that's why...
I've seen some hints about accessing endpoint behaviours like:
var whb = client.ChannelFactory.Endpoint.Behaviors.Find<WebHttpBehavior>();
But that only allows me to choose between xml and json.
whb.AutomaticFormatSelectionEnabled = false;
whb.DefaultOutgoingRequestFormat = WebMessageFormat.Xml;
I have a wsdl:
http://caqh.org/SOAP/WSDL/CORERule2.2.0.wsdl
I need to call the WCF service's RealTimeTransaciton with headers that that are:
Content-Type: application/soap+xml;charset=UTF-8;
Currently, by default I suppose, the call includes headers;
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
and Content-Type doesn't seem to be set.
So I tried to affect the headers of the request...
var addressHeaders = new List<AddressHeader> {
AddressHeader.CreateAddressHeader("Content-Type", "", "application/soap+xml;charset=UTF-8;"),
AddressHeader.CreateAddressHeader("Cache-Control", "", "no-cache"),
AddressHeader.CreateAddressHeader("Accept", "", "application/soap+xml;charset=UTF-8;")
};
var client = new CORETransactionsClient(binding, new EndpointAddress(new Uri(url),addressHeaders.ToArray()));
But to my surprise, the result of this is that these 'headers' are added within the soap Envelope headers, and not the headers for the transport!
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<Content-Type>application/soap+xml;charset=UTF-8;</Content-Type>
<Cache-Control>no-cache</Cache-Control>
<Accept>application/soap+xml;charset=UTF-8;</Accept>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
etc.... lol
My web.config service model:
<system.serviceModel>
<bindings>
<customBinding>
<binding name="CoreSoapBinding">
<textMessageEncoding messageVersion="Soap12" writeEncoding="UTF8" />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="https://my_vendor_url_for_service_that_is_Axis2_based" binding="customBinding"
bindingConfiguration="CoreSoapBinding" contract="CoreRule.CORETransactions"
name="CoreSoapPort"
endpointConfiguration="">
</endpoint>
</client>
</system.serviceModel>
How I call:
var msg = Create270X12Message(requestReferenceId, senderId, receiverId, requestDateStr, productionCall, prettyOutput);
var envelope = new COREEnvelopeRealTimeRequest
{
CORERuleVersion = "2.2.0",
Payload = string.Format("<![CDATA[{0}]]>", Convert.ToBase64String(Encoding.UTF8.GetBytes(msg))),
PayloadID = requestReferenceId.ToString(),
PayloadType = CoreRule2PayloadType_270_5010,
ProcessingMode = CoreRule2ProcessingMode_270_5010,
ReceiverID = receiverId,
SenderID = senderId,
TimeStamp = requestDateStr
};
var client = CreateRealTimeOnlineProxy(urlMissouiri, username, password, requestDateStr);
var response = client.RealTimeTransaction(envelope);
How can I add my collection of headers to the request itself, instead of the SOAP Envelope headers?

Authentication Issue with eBatNS Trading API trying to get SessionID

I'm trying to get a session ID using the eBatNS SOAP API.
The function which makes the call is pretty simple, but always returns an Authentication error. You can see the function below
public function get_ebay_session()
{
error_reporting(0);
$ruName = "Forward_Thinker-ForwardT-57fe-4-rybapdi";
$sessionID = "";
//Connect to eBay and get a list of all products
require_once 'eBay/EbatNs/EbatNs_ServiceProxy.php';
require_once 'eBay/EbatNs/GetSessionIDRequestType.php';
require_once 'eBay/EbatNs/EbatNs_Logger.php';
//Get a SessionID
$session = new EbatNs_Session('eBay/config/ebay.config.php');
print_r($session);
echo "<hr>";
$cs = new EbatNs_ServiceProxy($session);
$cs->attachLogger(new EbatNs_Logger(false, 'stdout', true, false));
print_r($cs);
echo "<hr>";
$req = new GetSessionIDRequestType();
$req->setRuName($ruName);
print_r($req);
echo "<hr>";
$result = $cs->GetSessionID($req);
$sessionID = $result->SessionID;
print_r($result);
echo "<hr>";
session_start();
$_SESSION['eBaySessionID'] = $sessionID;
$return = $ruName."\n".$sessionID;
$this->set(compact('return'));
}
As you can see I have attached a logger. The logger shows that this is the request being made.
<?xml version="1.0" encoding="utf-8"?><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/" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns="urn:ebay:apis:eBLBaseComponents" ><soap:Header><RequesterCredentials><eBayAuthToken>AgAAAA**AQAAAA**aAAAAA**wS7oUQ**nY+sHZ2PrBmdj6wVnY+sEZ2PrA2dj6wHloSkD5aGog+dj6x9nY+seQ**It4BAA**AAMAAA**CB7yrHTyG3kQbA6KOwf0ZO2MqyPs/Dfn5u5r8ZDVGeWNvB</eBayAuthToken><Credentials><AppId>ForwardT-57fe-41ea-b90e-52fd0b541b88</AppId><DevId>5eefba38-e226-4876-9ada-d8743f571aeb</DevId><AuthCert>b57984cb-ba9c-430c-a8fc-c08f9ac46e75</AuthCert></Credentials></RequesterCredentials></soap:Header><soap:Body><GetSessionIDRequest><Version><![CDATA[815]]></Version><RuName><![CDATA[Forward_Thinker-ForwardT-57fe-4-rybapdi]]></RuName></GetSessionIDRequest></soap:Body></soap:Envelope>
And that this is the response being returned:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<soapenv:Fault>
<faultcode xmlns:ns1="http://xml.apache.org/axis/">ns1:FailedCheck</faultcode>
<faultstring>Authorisation token is invalid.</faultstring>
<faultactor>http://www.ebay.com/ws/websvc/eBayAPI</faultactor>
<detail>
<FaultDetail>
<ErrorCode>931</ErrorCode>
<Severity>Error</Severity>
<DetailedMessage>Validation of the authentication token in API request failed.</DetailedMessage>
</FaultDetail>
</detail>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
My ebay.config.php file has all the correct keys and, as far as I can tell, all of the correct information. Does anyone have any tips for resolution?
Danny
This issue was caused by the eBatNS API sending a token from a previous request in the request to get a new token. This isn't supported by ebay.
This is resolved by setting the token mode on the session to 0 or false.
$session->setTokenMode(0)

How to send raw xml to SOAP server using Zend_Soap_Client?

I'm traying to send a raw request to a SOAP server. The only way I found to do this is creating a redundant Zend_Soap_Client_Common in order to invoke _dorequest. Is really that necessary? Is there any other way to send raw xml to the server?
Here's the code:
$client = new Zend_Soap_Client('http://212.170.239.71/appservices/ws/FrontendService?wsdl',
array(
'soap_version'=>SOAP_1_1
,'encoding' => 'UTF-8'
,'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_DEFLATE
,'location'=>'http://212.170.239.71/appservices/ws/FrontendService'
)
);
$location = 'http://212.170.239.71/appservices/ws/FrontendService';
$request = '<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<hb:getHotelValuedAvail xmlns:hb="http://axis.frontend.hydra.hotelbeds.com" xsi:type="xsd:anyType">
<HotelValuedAvailRQ echoToken="DummyEchoToken" sessionId="DummySessionId" xmlns="http://www.hotelbeds.com/schemas/2005/06/messages" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.hotelbeds.com/schemas/2005/06/messages HotelValuedAvailRQ.xsd">
<Language>CAS</Language>
<Credentials>
<User>XXXXX</User>
<Password>XXXXX</Password>
</Credentials>
<PaginationData pageNumber="1"/>
<ExtraParamList>
<ExtendedData type="EXT_ORDER">
<Name>ORDER_CONTRACT_PRICE</Name>
<Value>ASC</Value>
</ExtendedData>
</ExtraParamList>
<CheckInDate date="20110809"/>
<CheckOutDate date="20110811"/>
<Destination code="LPA" type="SIMPLE">
<ZoneList>
<Zone code="20" type="SIMPLE"/>
</ZoneList>
</Destination>
<OccupancyList>
<HotelOccupancy>
<RoomCount>1</RoomCount>
<Occupancy>
<AdultCount>2</AdultCount>
<ChildCount>0</ChildCount>
</Occupancy>
</HotelOccupancy>
</OccupancyList>
</HotelValuedAvailRQ>
</hb:getHotelValuedAvail>
</soapenv:Body>
</soapenv:Envelope>';
$clientCommon = new Zend_Soap_Client_Common($client, 'http://212.170.239.71/appservices/ws/FrontendService?wsdl',
array(
'soap_version'=>SOAP_1_1
,'encoding' => 'UTF-8'
,'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_DEFLATE
,'location'=>'http://212.170.239.71/appservices/ws/FrontendService'
));
$response = $client->_doRequest($clientCommon, $request, $location, 'getHotelValuedAvail', SOAP_1_1);
// With these two lines I've managed the call using "native" SoapClient
//$client = new SoapClient("http://212.170.239.71/appservices/ws/FrontendService?wsdl", array('trace'=>1));
//$response = $client->__doRequest($request, $location, 'getHotelValuedAvail', SOAP_1_1);
Thanks in advance.
Jorge