Having trouble parsing SOAP webservice using the library ksoap2 - web-services

Here is the structure of my SOAP webservice which I need to get the TxRefNum:
<?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:tem="http://tempuri.org/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header/>
<soap:Body>
<tem:MakeCreditCardPayment>
<tem:objCreditCardBookingPaymentRow>
<tem:ProfessionalUserMappingStudioID>18</tem:ProfessionalUserMappingStudioID>
<tem:ConsumerUserMappingStudioID>5</tem:ConsumerUserMappingStudioID>
<tem:Cost>5</tem:Cost>
<tem:CardNumber>4111111111111111</tem:CardNumber>
<tem:CardHolderName>Shyam</tem:CardHolderName>
<tem:ExpirationDate>042020</tem:ExpirationDate>
<tem:CVV>123</tem:CVV>
<tem:ProfessionalSessionID>320</tem:ProfessionalSessionID>
<tem:TxRefNum></tem:TxRefNum>
</tem:objCreditCardBookingPaymentRow>
</tem:MakeCreditCardPayment>
</soap:Body>
</soap:Envelope>
I am using ksoap2 library to parse the following data, but am unable to find a proper solution to it. Here's what I am doing:
final String NAMESPACE = "http://tempuri.org/";
final String URL = NewURLs.BASE_URL + "api/PaymentService.asmx";
final String SOAP_ACTION = "http://tempuri.org/MakeCreditCardPayment";
final String METHOD_NAME = "MakeCreditCardPayment";
final String INNER_METHOD_NAME = "tem:objCreditCardBookingPaymentRow";
// the above parameter can be taken from the users web service
// (?WSDL)
// url
SoapObject request = new SoapObject(NAMESPACE,METHOD_NAME);
SoapObject innerRequest = new SoapObject(NAMESPACE,INNER_METHOD_NAME);
innerRequest.addProperty("tem:ProfessionalUserMappingStudioID", bookingDetailsList.get(0).getUserMappingStudioID());
innerRequest.addProperty("tem:ConsumerUserMappingStudioID",loginCredentials.getUserMappingStudioId());
innerRequest.addProperty("tem:Cost",bookingDetailsList.get(0).getCost());
innerRequest.addProperty("tem:CardNumber", creditCardNo);
innerRequest.addProperty("tem:CardHolderName", creditCardHolder);
innerRequest.addProperty("tem:ExpirationDate", expirationDate);
innerRequest.addProperty("tem:CVV", cvv);
innerRequest.addProperty("tem:ProfessionalSessionID",bookingDetailsList.get(0).getProfessionalSessionID());
innerRequest.addProperty("tem:TxRefNum", "");
request.addProperty("tem:objCreditCardBookingPaymentRow",innerRequest);
utils.sysOut("some text", "" + request);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.call(SOAP_ACTION, envelope);
SoapObject resultsRequestSOAP = (SoapObject) envelope.bodyIn;
String str = resultsRequestSOAP.toString();
Log.v("TAG_SOAP_ACTION", str);

Try like this:
SoapObject res=(SoapObject)envelope.bodyIn;
SoapObject t=(SoapObject)res.getProperty("MakeCreditCardPayment");
for(int i=0; i<t.getPropertyCount(); i++){
SoapObject carditCard=(SoapObject)t.getProperty(i);
String userID = carditCard.getProperty("ProfessionalUserMappingStudioID").toString();
}

Related

500 Internal Server Error error in Webservice request

I have an existing jar which sends web-service request from one of our application server to another. Below is the code for sending the request
public IUsbMessage executeOutboundRequest(IUsbMessage paramIUsbMessage)
{
IUsbMessage localIUsbMessage = UsbMessageFactory.createUbusMessage();
try
{
LogManager.logDebug("ServiceProvider:- Enter executeOutboundRequest");
Object[] arrayOfObject = (Object[])paramIUsbMessage.getPayload();
NVPVO localNVPVO = (NVPVO)arrayOfObject[1];
String str1 = (String)localNVPVO.getHashmap().get("endPointUrl");
String str2 = (String)localNVPVO.getHashmap().get("respTag");
String str3 = (String)localNVPVO.getHashmap().get("body");
str3 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><FIXML xsi:schemaLocation=\"http://www.oracle.com/fixml AcctInq.xsd\" xmlns=\"http://www.oracle.com/fixml\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" + str3.trim();
LogManager.logDebug("ServiceProvider:- RequestXMLMsg" + str3);
MessageFactory localMessageFactory = MessageFactory.newInstance();
SOAPMessage localSOAPMessage1 = localMessageFactory.createMessage();
SOAPFactory localSOAPFactory = SOAPFactory.newInstance();
SOAPBody localSOAPBody = localSOAPMessage1.getSOAPBody();
SOAPElement localSOAPElement1 = localSOAPBody.addChildElement(localSOAPFactory.createName("executeService"));
SOAPElement localSOAPElement2 = localSOAPElement1.addChildElement(localSOAPFactory.createName("arg_0_0"));
localSOAPElement2.addTextNode(str3);
localSOAPMessage1.saveChanges();
localSOAPMessage1.writeTo(System.out);
SOAPConnectionFactory localSOAPConnectionFactory = SOAPConnectionFactory.newInstance();
SOAPConnection localSOAPConnection = localSOAPConnectionFactory.createConnection();
LogManager.logDebug("ServiceProvider:- endPointUrl" + str1);
LogManager.logDebug("ServiceProvider:- respTag" + str2);
URL localURL = new URL(str1);
SOAPMessage localSOAPMessage2 = localSOAPConnection.call(localSOAPMessage1, localURL);
DocumentBuilderFactory localDocumentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder localDocumentBuilder = localDocumentBuilderFactory.newDocumentBuilder();
Document localDocument = localDocumentBuilder.newDocument();
Element localElement1 = null;
Element localElement2 = null;
Text localText = null;
Element localElement3 = null;
Iterator localIterator = localSOAPMessage2.getSOAPBody().getChildElements();
Object localObject2;
Object localObject3;
while (localIterator.hasNext())
{
localObject1 = (SOAPElement)localIterator.next();
localElement1 = localDocument.createElement(((SOAPElement)localObject1).getNodeName());
localObject2 = ((SOAPElement)localObject1).getAttributes();
Object localObject4;
if (((NamedNodeMap)localObject2).getLength() > 0) {
for (int i = 0; i < ((NamedNodeMap)localObject2).getLength(); i++)
{
localObject4 = ((NamedNodeMap)localObject2).item(i);
localElement1.setAttribute(((Node)localObject4).getNodeName(), ((Node)localObject4).getNodeValue());
}
}
localElement3 = localElement1;
localObject3 = ((SOAPElement)localObject1).getChildElements();
while (((Iterator)localObject3).hasNext())
{
localObject4 = (SOAPElement)((Iterator)localObject3).next();
localElement1 = localDocument.createElement(((SOAPElement)localObject4).getNodeName());
NamedNodeMap localNamedNodeMap = ((SOAPElement)localObject1).getAttributes();
if (localNamedNodeMap.getLength() > 0) {
for (int j = 0; j < localNamedNodeMap.getLength(); j++)
{
Node localNode = localNamedNodeMap.item(j);
localElement1.setAttribute(localNode.getNodeName(), localNode.getNodeValue());
}
}
localElement2 = localElement1;
localText = localDocument.createTextNode(((SOAPElement)localObject4).getValue());
localElement2.appendChild(localText);
localElement3.appendChild(localElement2);
}
The data which is being passed to the class file is as below containing the request XML and other details
respTag=AcctInqRs,
body=<Header>
<RequestHeader>
<MessageKey>
<RequestUUID>Req_159538426</RequestUUID>
<ServiceRequestId>AcctInq</ServiceRequestId>
<ServiceRequestVersion>10.2</ServiceRequestVersion>
<ChannelId>OR</ChannelId>
<LanguageId></LanguageId>
</MessageKey>
<RequestMessageInfo>
<BankId>54</BankId>
<TimeZone></TimeZone>
<EntityId></EntityId>
<EntityType></EntityType>
<ArmCorrelationId></ArmCorrelationId>
<MessageDateTime>2020-02-23T14:27:22.627</MessageDateTime>
</RequestMessageInfo>
<Security>
<Token>
<PasswordToken>
<UserId></UserId>
<Password></Password>
</PasswordToken>
</Token>
<FICertToken></FICertToken>
<RealUserLoginSessionId></RealUserLoginSessionId>
<RealUser></RealUser>
<RealUserPwd></RealUserPwd>
<SSOTransferToken></SSOTransferToken>
</Security>
</RequestHeader>
</Header>
<Body>
<AcctInqRequest>
<AcctInqRq>
<AcctId>
<AcctId>1101614</AcctId>
</AcctId>
</AcctInqRq>
</AcctInqRequest>
</Body>
</FIXML>,
reqhdr.requestuuid=FINCORE240716215711,
endPointUrl=https://ORPREPROD.domain.com:20322/fiwebservice/FIWebService,
reqhdr.messagedatetime=2020-04-21T21:57:11.000,
reqhdr.servicerequestversion=10.2,
reqhdr.origchannelid=COR,
reqhdr.bankid=54,
reqhdr.servicerequestid=AcctInq
Now the issue is that the request is being sent from server A to server B. Once the request reaches server B it is throwing error "HTTP/1.1 500 Internal Server Error" and the below xml is seen in the logs
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header/>
<env:Body>
<env:Fault xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<faultcode>SOAP-ENV:Client</faultcode>
<faultstring>**Failed to get operation name from incoming request**</faultstring>
</env:Fault>
</env:Body>
</env:Envelope>
On both the servers our application is deployed on Weblogic and the above errors are from weblogic logs. Can anyone please help me to determine the exact cause of this error, I am totally stuck and clueless about what to do.
The same request XML when sent through SOAP UI works perfectly.
The below request XML works in SOAPUI
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:web="http://webservice.fiusb.ci.ibm.com/">
<soapenv:Header/>
<soapenv:Body>
<web:executeService>
<arg_0_0><![CDATA[<FIXML xsi:schemaLocation="http://www.finacle.com/fixml AcctInq.xsd" xmlns="http://www.finacle.com/fixml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Header><RequestHeader><MessageKey><RequestUUID>Req_158495384262711</RequestUUID><ServiceRequestId>AcctInq</ServiceRequestId><ServiceRequestVersion>10.2</ServiceRequestVersion><ChannelId>COR</ChannelId><LanguageId></LanguageId></MessageKey><RequestMessageInfo><BankId>54</BankId><TimeZone></TimeZone><EntityId></EntityId><EntityType></EntityType><ArmCorrelationId></ArmCorrelationId><MessageDateTime>2020-02-23T14:27:22.627</MessageDateTime></RequestMessageInfo><Security><Token><PasswordToken><UserId></UserId><Password></Password></PasswordToken></Token><FICertToken></FICertToken><RealUserLoginSessionId></RealUserLoginSessionId><RealUser></RealUser><RealUserPwd></RealUserPwd><SSOTransferToken></SSOTransferToken></Security></RequestHeader></Header><Body><AcctInqRequest><AcctInqRq><AcctId><AcctId>1100161916154</AcctId></AcctId></AcctInqRq></AcctInqRequest></Body></FIXML>
]]></arg_0_0>
</web:executeService>
</soapenv:Body>
</soapenv:Envelope>
The below XML throws the same error "Failed to get operation name from incoming request"
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:web="http://webservice.fiusb.ci.ibm.com">
<soapenv:Header/>
<soapenv:Body>
<web:executeService>
<arg_0_0><![CDATA[<FIXML xsi:schemaLocation="http://www.finacle.com/fixml AcctInq.xsd" xmlns="http://www.finacle.com/fixml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Header><RequestHeader><MessageKey><RequestUUID>Req_158495384262711</RequestUUID><ServiceRequestId>AcctInq</ServiceRequestId><ServiceRequestVersion>10.2</ServiceRequestVersion><ChannelId>COR</ChannelId><LanguageId></LanguageId></MessageKey><RequestMessageInfo><BankId>54</BankId><TimeZone></TimeZone><EntityId></EntityId><EntityType></EntityType><ArmCorrelationId></ArmCorrelationId><MessageDateTime>2020-02-23T14:27:22.627</MessageDateTime></RequestMessageInfo><Security><Token><PasswordToken><UserId></UserId><Password></Password></PasswordToken></Token><FICertToken></FICertToken><RealUserLoginSessionId></RealUserLoginSessionId><RealUser></RealUser><RealUserPwd></RealUserPwd><SSOTransferToken></SSOTransferToken></Security></RequestHeader></Header><Body><AcctInqRequest><AcctInqRq><AcctId><AcctId>1100161916154</AcctId></AcctId></AcctInqRq></AcctInqRequest></Body></FIXML>
]]></arg_0_0>
</web:executeService>
</soapenv:Body>
</soapenv:Envelope>
Notice the forward slash(/) at the end of namespace. If the slash is not there in the namespace it throws the error in SOAP UI.
Please help me to understand how can I change namespace in my java code

jaxb adding namespace to element

According to my task I have to invoke SOAP service. So, I have generated java classes from wsdl using xjc. But I have a problem invoking SOAP service. My application generates this request:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"/><soap:Body>
<typ:SendMessage xmlns:ns4="http://test.user.kz/UserInfo" xmlns:q1="http://test.user.kz/CustomerInfo" xmlns:typ="http://test.user.kz/MyChannel/v1/Types">
<request>
<requestInfo>
<messageId>26e96b11-8f82-421e-829a</messageId>
</requestInfo>
<requestData>
<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="q1:PaymentPackageRequestType">
<q1:methodName>testMethod</q1:methodName>
</data>
</requestData>
</request>
</typ:SendMessage></soap:Body></soap:Envelope>
But I need in my SOAP request I need to specify namespace in data tag, lik this:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"/><soap:Body>
<typ:SendMessage xmlns:ns4="http://test.user.kz/UserInfo" xmlns:q1="http://test.user.kz/CustomerInfo" xmlns:typ="http://test.user.kz/MyChannel/v1/Types">
<request>
<requestInfo>
<messageId>26e96b11-8f82-421e-829a</messageId>
</requestInfo>
<requestData>
<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="q1:PaymentPackageRequestType" **xmlns:q1="http://payments.bee.kz/PaymentPackage"**>
<q1:methodName>testMethod</q1:methodName>
</data>
</requestData>
</request>
</typ:SendMessage></soap:Body></soap:Envelope>
Otherwise target SOAP service gives me error:
XML namespace prefix 'q1' is not defined.
How it possible to specify namespace in data tag?
This is my current package-info:
#javax.xml.bind.annotation.XmlSchema(
xmlns = {
#javax.xml.bind.annotation.XmlNs(prefix = "typ",
namespaceURI = "http://test.user.kz/MyChannel/v1/Types"),
#javax.xml.bind.annotation.XmlNs(prefix = "q1",
namespaceURI = "http://test.user.kz/CustomerInfo")
},
elementFormDefault = javax.xml.bind.annotation.XmlNsForm.UNQUALIFIED,
attributeFormDefault = javax.xml.bind.annotation.XmlNsForm.UNSET
)
package kz.uni.gen;
So I couldn't add namespace xmlns:q1="http://test.user.kz/CustomerInfo" to data tag in SOAP request. How can I add this namespace declaration or move namespace declaration from SendMessage tag?
so using JAXB it is not possible. Therefore I am manually added namespace in required element. This is full snippet:
Document document = null;
try {
document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Marshaller marshaller = JAXBContext.newInstance(SendMessage.class).createMarshaller();
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.setProperty("com.sun.xml.bind.characterEscapeHandler", new CharacterEscapeHandler() {
#Override
public void escape(char[] buf, int start, int len, boolean b, Writer out) throws IOException {
out.write(buf, start, len);
}
});
QName name = new QName(NAMESPACE_URI, SendMessage.class.getSimpleName());
JAXBElement<SendMessage> root = new JAXBElement<SendMessage>(name, SendMessage.class, from);
StringWriter writer1 = new StringWriter();
marshaller.marshal(root, writer1);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
Element node = dbf
.newDocumentBuilder()
.parse(new ByteArrayInputStream(writer1.toString().getBytes(StandardCharsets.ISO_8859_1)))
.getDocumentElement();
Attr attr1 = document.createAttribute("xmlns:q1");
attr1.setValue("http://test.user.kz/CustomerInfo");
node.getElementsByTagName("data").item(0).getAttributes().setNamedItem(node.getOwnerDocument().importNode(attr1, true));
return node;
} catch (Exception e) {
throw new Exception("Unable to transform POJO to XML SOAP message ", e);
}

gSoap EWS "Error 500: Internal Server Error"

I have some problems with ews(gSoap).
I have next code:
ExchangeServiceBindingProxy *proxy = new ExchangeServiceBindingProxy(endpoint.c_str());
soap *pSoap = proxy->soap;
pSoap->userid = "Ivan1";
pSoap->passwd = "1";
pSoap->ntlm_challenge = "";
pSoap->authrealm = "Ursa-Minor";
pSoap->ssl_flags = SOAP_SSL_NO_AUTHENTICATION;
pSoap->keep_alive = true;
pSoap->mode = SOAP_IO_KEEPALIVE;
//get root folder ID
ns3__DistinguishedFolderIdType *dfit = new ns3__DistinguishedFolderIdType();
dfit->Id = ns3__DistinguishedFolderIdNameType__inbox;
//set the props that we want to retrieve
ns3__FolderResponseShapeType *frst = new ns3__FolderResponseShapeType();
frst->BaseShape = ns3__DefaultShapeNamesType__AllProperties;
//get folder
ns1__GetFolderType *gftRoot = new ns1__GetFolderType();
gftRoot->FolderIds = new ns3__NonEmptyArrayOfBaseFolderIdsType();
gftRoot->FolderIds->__size_NonEmptyArrayOfBaseFolderIdsType = 1;
gftRoot->FolderIds->__union_NonEmptyArrayOfBaseFolderIdsType = new __ns3__union_NonEmptyArrayOfBaseFolderIdsType();
gftRoot->FolderIds->__union_NonEmptyArrayOfBaseFolderIdsType->union_NonEmptyArrayOfBaseFolderIdsType.DistinguishedFolderId = dfit;
gftRoot->FolderIds = (ns3__NonEmptyArrayOfBaseFolderIdsType*)dfit;
gftRoot->FolderShape = frst;
__ns1__GetFolderResponse response;
int ret = proxy->GetFolder(gftRoot, response);
I`m using OpenSSL and NTLM libs(WITH_OPENSSL, WITH_NTLM).
As a resault gSoap generates this SOAP:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:ns3="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns:ns1="http://schemas.microsoft.com/exchange/services/2006/messages">
<SOAP-ENV:Header>
<ns3:RequestServerVersion SOAP-ENV:mustUnderstand="1" Version="Exchange2010">
</ns3:RequestServerVersion>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ns1:GetFolder xsi:type="ns1:GetFolderType">
<ns1:FolderShape>
<ns3:BaseShape>AllProperties</ns3:BaseShape>
</ns1:FolderShape>
<ns1:FolderIds Id="inbox" xsi:type="ns3:DistinguishedFolderIdType"> </ns1:FolderIds>
</ns1:GetFolder>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Response from server:
HTTP/1.1 500 Internal Server Error
Cache-Control: private
Transfer-Encoding: chunked
Content-Type: text/xml; charset=utf-8
Server: Microsoft-IIS/7.0
Set-Cookie: exchangecookie=88bb510ab2ef4191a42c6cf9aada1614; expires=Fri, 24-Oct-2014 09:45:45 GMT; path=/; HttpOnly
X-EwsPerformanceData: RpcC=0;RpcL=0;LdapC=0;LdapL=0;
X-AspNet-Version: 2.0.50727
X-Powered-By: ASP.NET
Date: Thu, 24 Oct 2013 09:45:45 GMT
Connection: close
5d0
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<s:Fault>
<faultcode xmlns:a="http://schemas.microsoft.com/exchange/services/2006/types">a:ErrorSchemaValidation</faultcode>
<faultstring xml:lang="en-US">The request failed schema validation: The xsi:type attribute value 'http://schemas.microsoft.com/exchange/services/2006/types:DistinguishedFolderIdType' is not valid for the element 'http://schemas.microsoft.com/exchange/services/2006/messages:FolderIds', either because it is not a type validly derived from the type in the schema, or because it has xsi:type derivation blocked.</faultstring>
<detail>
<e:ResponseCode xmlns:e="http://schemas.microsoft.com/exchange/services/2006/errors">ErrorSchemaValidation</e:ResponseCode>
<e:Message xmlns:e="http://schemas.microsoft.com/exchange/services/2006/errors">The request failed schema validation.</e:Message>
<t:MessageXml xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<t:LineNumber>2</t:LineNumber>
<t:LinePosition>519</t:LinePosition>
<t:Violation>The xsi:type attribute value 'http://schemas.microsoft.com/exchange/services/2006/types:DistinguishedFolderIdType' is not valid for the element 'http://schemas.microsoft.com/exchange/services/2006/messages:FolderIds', either because it is not a type validly derived from the type in the schema, or because it has xsi:type derivation blocked.
</t:Violation>
</t:MessageXml>
</detail>
</s:Fault>
</s:Body>
</s:Envelope>
As you can see, the problem is in line
<ns1:FolderIds Id="inbox" xsi:type="ns3:DistinguishedFolderIdType"
Server don`t want to see xsi:type="ns3:DistinguishedFolderIdType" in this line. In original SOAP it looks like:
<FolderIds>
<DistinguishedFolderId Id="inbox" xmlns="http://schemas.microsoft.com/exchange/services/2006/types" />
</FolderIds>
So. How to solve this problem?
IStar,
First off, I'm not familiar with gSOAP nor am I familiar with this syntax. In fact, I don't expect to answer your question but I'll give it a shot. With that said, gSOAP is trying to create XML that is not supported by EWS. I think the following lines are incorrect, and there probably needs to be another line or two:
gftRoot->FolderIds->__union_NonEmptyArrayOfBaseFolderIdsType->union_NonEmptyArrayOfBaseFolderIdsType.DistinguishedFolderId = dfit;
gftRoot->FolderIds = (ns3__NonEmptyArrayOfBaseFolderIdsType*)dfit;
I think that second line is instructing gSOAP to make the FolderIds element to be something it shouldn't be. It looks like there is some sort of conflation of the FolderIds and DistinguishedFolderId element structure.
Perhaps it should look something like:
ns3__NonEmptyArrayOfBaseFolderIdsType *fids = new ns3__NonEmptyArrayOfBaseFolderIdsType();
fids->DistinguishedFolderId = dfit
fids->__size_NonEmptyArrayOfBaseFolderIdsType = 1;
gftRoot->FolderIds = fids;
Well, i figured out how to make it works:
//get folder
ns1__GetFolderType *gftRoot = new ns1__GetFolderType();
gftRoot->FolderIds = new ns3__NonEmptyArrayOfBaseFolderIdsType();
gftRoot->FolderIds->__size_NonEmptyArrayOfBaseFolderIdsType = 1; //there we specify how many folders elements in FolderIds array
gftRoot->FolderIds->__union_NonEmptyArrayOfBaseFolderIdsType = new __ns3__union_NonEmptyArrayOfBaseFolderIdsType(); //create one element of array
gftRoot->FolderIds->__union_NonEmptyArrayOfBaseFolderIdsType->__union_NonEmptyArrayOfBaseFolderIdsType = 2; //this indicates, which class/structure are taken from union
gftRoot->FolderIds->__union_NonEmptyArrayOfBaseFolderIdsType->union_NonEmptyArrayOfBaseFolderIdsType.DistinguishedFolderId = dfit; //push dfit to element
gftRoot->FolderShape = frst;
__ns1__GetFolderResponse response;
int ret = proxy->GetFolder(gftRoot, response);

How to pass UserNameToken to ASMX service?

I have an asmx web service and a test console app. I have added web service reference to the console app and calling it like this
Employee.Employee e = new TestService.Employee.Employee();
e.SomeMethod();
On every web service call there is a validation check which looks like this
private bool IsUserNameTokenPresent()
{
//Get current SOAP context
SoapContext ctxt = RequestSoapContext.Current;
UsernameToken user = null;
if (ctxt == null)
{
//This request is using a different protocol other than SOAP.
return false;
}
//Iterate through all Security tokens
foreach(SecurityToken tok in ctxt.Security.Tokens)
{
if (tok is UsernameToken)
{
user = (UsernameToken)tok;
}
}
if (user == null)
return false;
return true;
}
Question: How do I pass the Security Token so that I can test this service. Its always null.
Finally found the answer for this. I had to create my own SOAP header manually and pass it with the request. Here is some code. I had to create Nonce dynamically for every call, I will post it here if someone wants the code for that.
XmlDocument doc = new XmlDocument();
doc.InnerXml = #"<?xml version='1.0' encoding='utf-8'?>
<soap:Envelope
xmlns:wsu='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd'
xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'
xmlns:wsse='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'>
<soap:Header>
<wsse:Security soap:mustUnderstand='1'>
<wsse:UsernameToken wsu:Id='uuid_faf0159a-6b13-4139-a6da-cb7b4100c10c'>
<wsse:Username>UserID</wsse:Username>
<wsse:Password>Pass</wsse:Password>
<wsse:Nonce>" + nonce + #"</wsse:Nonce>
<wsu:Created>" + date + #"</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</soap:Header>
<soap:Body>
<FindBySelfId>
<specification>
<LastName>" + lastname + #"</LastName>
<FirstName>" + firstname + #"</FirstName>
<DateOfBirth>" + dob + #"</DateOfBirth>
<HomeZipCode>" + zip + #"</HomeZipCode>
<SSN4>" + ssn + #"</SSN4>
</specification>
</FindBySelfId >
</soap:Body>
</soap:Envelope>";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://localhost/Employee/employee.asmx");
req.Headers.Add("SOAPAction", "https://<Namespace here>");
req.ContentType = "text/xml;charset=\"utf-8\"";
req.Accept = "text/xml";
req.Method = "POST";
Stream stm = req.GetRequestStream();
doc.Save(stm);
stm.Close();

Authentication headers not working in ONVIF request?

I am writing an API in C for authenticating user using ONVIF. I write some code to make authentication header. But when I sent these headers he server respond that "The security token could not be authenticated or authorized"
unsigned int nonce_int = 0, i = 0;
time_t utcTime = 0;
struct tm *timeInfo = NULL;
char sha1_input[100] = { 0 }, sha1_input1[100] = { 0 };
SHA1Context sha = { 0 };
nonce_int = GetRandomNumber();
encode_base64(sizeof(nonce_int), (char*)&nonce_int, nonceLen, noncestr);
utcTime = time(NULL);
timeInfo = localtime(&utcTime);
strftime(timestr, timeLen, "%Y-%m-%dT%H:%M:%SZ", timeInfo);
printf("\nTime in String Format = %s", timestr);
sprintf(sha1_input, "%d+%d+%s", nonce_int, utcTime, password);
strcpy(sha1_input1, sha1_input);
SHA1Reset(&sha);
SHA1Input(&sha, (const unsigned char*)sha1_input, strlen(sha1_input));
if(!SHA1Result(&sha))
{
printf("\nERROR-- could not compute message digest");
}
else
{
memset(sha1_input, 0x00, sizeof(sha1_input));
/*sprintf(sha1_input, "%X%X%X%X%X", sha.Message_Digest[0], sha.Message_Digest[1],
sha.Message_Digest[2], sha.Message_Digest[3], sha.Message_Digest[4]);*/
sprintf(sha1_input, "%u%u%u%u%u", sha.Message_Digest[0], sha.Message_Digest[1],
sha.Message_Digest[2], sha.Message_Digest[3], sha.Message_Digest[4]);
printf("\nSHA1 Digest = %s", sha1_input);
encode_base64(strlen(sha1_input), sha1_input, digestLen, digeststr);
printf("\nSHA1 Digest Base64 Encoded = %s", digeststr);
}
after that I sent this request on HTTP using POST method this.
snprintf(postData, sizeof(postData),
"<?xml version=\"1.0\" encoding=\"utf-8\"?>"
"<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://www.w3.org/2003/05/soap-envelope\""
"xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401"
"-wss-wssecurity-secext-1.0.xsd\""
"xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-"
"200401-wss-wssecurity-utility-1.0.xsd\""
"xmlns:tds=\"http://www.onvif.org/ver20/ptz/wsdl\">"
"<SOAP-ENV:Header><wsse:Security><wsse:UsernameToken>"
"<wsse:Username>%s</wsse:Username>"
"<wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-"
"200401-wss-username-token-profile-1.0#PasswordDigest\">"
"%s</wsse:Password><wsse:Nonce>%s</wsse:Nonce>"
"<wsu:Created>%s</wsu:Created></wsse:UsernameToken>"
"</wsse:Security></SOAP-ENV:Header><SOAP-ENV:Body>"
"<tds:GetNodes>"
"</SOAP-ENV:Body></SOAP-ENV:Envelope>",
username, base64EncDigest, nonce_char, time_char);
Response:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope"
xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsa5="http://www.w3.org/2005/08/addressing"
xmlns:c14n="http://www.w3.org/2001/10/xml-exc-c14n#"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:ptzimg2="http://www.onvif.org/ver10/schema"
xmlns:ptzimg3="http://www.w3.org/2005/05/xmlmime"
xmlns:ptzimg4="http://docs.oasis-open.org/wsn/b-2"
xmlns:ptzimg5="http://docs.oasis-open.org/wsrf/bf-2"
xmlns:ptzimg6="http://docs.oasis-open.org/wsn/t-1"
xmlns:ptzimg1="http://www.onvif.org/ver20/ptz/wsdl"
xmlns:ptzimg7="http://www.onvif.org/ver20/imaging/wsdl"
xmlns:ter="http://www.onvif.org/ver10/error">
<SOAP-ENV:Header></SOAP-ENV:Header>
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<SOAP-ENV:Code>
<SOAP-ENV:Value>
SOAP-ENV:Sender
</SOAP-ENV:Value>
<SOAP-ENV:Subcode>
<SOAP-ENV:Value>
wsse:FailedAuthentication
</SOAP-ENV:Value>
</SOAP-ENV:Subcode>
</SOAP-ENV:Code>
<SOAP-ENV:Reason>
<SOAP-ENV:Text xml:lang="en">
The security token could not be authenticated or authorized
</SOAP-ENV:Text>
</SOAP-ENV:Reason>
<SOAP-ENV:Node>
http://www.w3.org/2003/05/soap-envelope/node/ultimateReceiver
</SOAP-ENV:Node>
<SOAP-ENV:Role>
http://www.w3.org/2003/05/soap-envelope/role/ultimateReceiver
</SOAP-ENV:Role>
<SOAP-ENV:Detail></SOAP-ENV:Detail>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
am I doing anything wrong? Especially when created digest? Thanks
Check the device time. Assuming that you are generating correct password digest it can be problem that device has different time then you use to sign your request and then the password digest can act like expired.