binary signature problem using zeep in python - soap

I am currently trying to use zeep to consume a soap service, but in the binary signature part zeep does not generate the xml as expected, the signature is expected like this:
<wsse:UsernameToken wsu:Id="UsernameToken-D01D11BA2CAF83D4FD16720147918422">
<wsse:Username>2-90155</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">wzxxxx</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">v47Jj/bIOMI5PIWFsdzalw==</wsse:Nonce>
<wsu:Created>2022-12-26T00:33:11.842Z</wsu:Created>
</wsse:UsernameToken>
but my code generates the signature like this:
<wsse:UsernameToken>
<wsse:Username>2-901705</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">wzPxxxx</wsse:Password>
</wsse:UsernameToken>
<wsu:Timestamp wsu:Id="id-1b7e34ff-0f38-4651-a456-8a4f4011903b">
<wsu:Created>2022-12-25T20:03:16Z</wsu:Created>
<wsu:Expires>2022-12-25T20:08:16Z</wsu:Expires>
</wsu:Timestamp>
not generate is tag <wsse:Nonce EncodingType
my code
timestamp_token = WSU.Timestamp()
today_datetime = datetime.datetime.today()
expires_datetime = today_datetime + datetime.timedelta(minutes = 5)
timestamp_elements = [
WSU.Created(today_datetime.strftime("%Y-%m-%dT%H:%M:%SZ")),
WSU.Expires(expires_datetime.strftime("%Y-%m-%dT%H:%M:%SZ"))
]
timestamp_token.extend(timestamp_elements)
user_name_token = UsernameToken('2-95','wzxxxxx',timestamp_token=timestamp_token)
wsdl_client = Client(
wsdl=wsdl_url,
wsse=[user_name_token, signature],
transport=transport
)
Has anyone had this mishap?

Related

Postman test fails while parsing the xml soap response

I am using POSTMAN to send a SOAP request and below is my soapenv response received. I would like to test for the below value received in my postman test, but the post man test fails, could someone advise on what to do here ?
LicStatus
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:schemas.general.com.au:api:other">
<soapenv:Header xmlns:urn="urn:schemas.general.com.au:api:other" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<header xmlns:urn="urn:schemas.general.com.au:api:other" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://schemas.cordys.com/General/1.0/">
<msg-id>005056B9-3921-A1E9-A327-64509F7362DC</msg-id>
<messageoptions noreply="true"/>
</header>
</soapenv:Header>
<soapenv:Body>
<getSupplierDataResponse xmlns:urn="urn:schemas.general.com.au:api:other" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="urn:schemas.general.com.au:api:other" xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns6="http://schemas.cordys.com/default_005056B9-5D92-A1E9-904D-128C719CE2DD" xmlns:ns5="http://schemas.cordys.com/casemanagement/1.0" xmlns:ns4="http://schemas.XXTGGHG.org/2004/07/STRD.Models" xmlns:ns3="urn:schemas.general.com.au:canonical:technical:v1" xmlns:ns2="urn:schemas.general.com.au:api:other" xmlns:bpm="http://schemas.cordys.com/default" xmlns:sm="http://www.w3.org/2005/07/scxml" xmlns:instance="http://schemas.cordys.com/bpm/instance/1.0">
<CustomerData>
<DateLicenceExpires>28/01/2020</DateLicenceExpires>
<Demonstration_Method>Certification</Demonstration_Method>
<AuditLastAuditDate>05/03/2018</AuditLastAuditDate>
<AuditOutcome>Non Compliance</AuditOutcome>
<HeadOfficeRegion/>
<ScopeOfLicencing>YES</ScopeOfLicencing>
<LicStatus>Licensed</LicStatus>
</CustomerData>
<OperationResult xmlns="urn:schemas.general.com.au:canonical:technical:v1">
<Status>00</Status>
<StatusMessage>Success</StatusMessage>
</OperationResult>
</getSupplierDataResponse>
</soapenv:Body>
</soapenv:Envelope>
Below is the post man test:
pm.test('Verify the LicStatus', function() {
var responseJson = xml2Json(responseBody);
pm.expect(responseJson.results[0].LicStatus).to.eql("Licensed");
})
Try something like this:
pm.test('Verify the LicStatus', function() {
var xmlTree = xml2Json(responseBody);
var licenseStatus = xmlTree['soapenv:Envelope']['soapenv:Body'].getSupplierDataResponse.CustomerData.LicStatus;
pm.expect(licenseStatus).to.eql("Licensed");
})

Basic auth credentials using headers in soap on groovy

I'm trying to connect to WSDL server, which requires basic auth along with the body. I tried hitting with SOAPUI, and was able to do so. While working for the same in groovy and using wslite package for SOAP call, I'm getting error as "Password required".
I tried the tutorial on https://github.com/jwagenleitner/groovy-wslite, but the method described (in Usage block) didn't help.
I'm using groovy for this.
Below is the raw code from SOAP UI, with response 200OK
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:w="http://xmlns.oracle.com/Enterprise/Tools/schemas/W_CHKLST_CREATE_REQ.1">
<soapenv:Header><wsse:Security soapenv:mustUnderstand="1" 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"><wsse:UsernameToken wsu:Id="UsernameToken-83C962CC24EAB67F1D15586306447678"><wsse:Username>userName</wsse:Username><wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">Password</wsse:Password><wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">JLTdeK6Yg3D64+2qz5xnbA==</wsse:Nonce><wsu:Created>2019-05-23T16:57:24.767Z</wsu:Created></wsse:UsernameToken></wsse:Security></soapenv:Header>
<soapenv:Body>
<w:helloWorld/>
</soapenv:Body>
</soapenv:Envelope>
which results in a 200OK from SOAPUI
HTTP/1.1 200 OK
Date: Wed, 22 May 2019 21:54:12 GMT
Content-Type: text/xml; charset=UTF-8
Content-Length: 3570
My Groovy Code,
def client = new SOAPClient("URL of WSDL")
def response = client.send(SOAPAction: "someAction",
connectTimeout:10000,
readTimeout:20000,
useCaches:false,
followRedirects:false) {
version SOAPVersion.V1_2 // SOAPVersion.V1_1 is default
soapNamespacePrefix "soapenv" // "soap-env" is default
envelopeAttributes "xmlns:ns":"http://example.weather.org"
header {
security("xmlns:ns20":"http://SecurityOpenXSD"){
"ns20:Username"("username")
"ns20:Password"("password")
}
}
body {
"ns:helloWorld" {
}
}
}
which gives soap xml as
<soapenv:Header>
<wsse:Security soapenv:mustUnderstand='1'
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'>
<wsse:UsernameToken wsu:Id='UsernameToken-83C962CC24EAB67F1D15586299636605'>
<wsse:Username>userName</wsse:Username>
<wsse:Password
Type='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText'>
password
</wsse:Password>
<wsse:Nonce
EncodingType='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary'>
JLTdeK6Yg3D64+2qz5xnbA==
</wsse:Nonce>
<wsu:Created>2019-05-23T10:07:52.913Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
But i get error as password required,
<?xml version="1.0" ?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope">
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<Code><Value>SOAP-ENV:Receiver</Value></Code>
<Reason><Text>null</Text></Reason>
<Detail><IBResponse type="error" xmlns=""><DefaultTitle> Error Response</DefaultTitle>
<StatusCode>20</StatusCode>
<DefaultMessage><![CDATA[User Password required]]></DefaultMessage>
</IBResponse></Detail></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>

Cannot invoke method last() on null object in soap ui

I am new to soap ui. I am trying to fetch list of files using groovy and trigger the soap UI for the same files. groovy script us running fine.but in request I am getting response stating that "Cannot invoke method last() on null object".Am I missing something:
Here is my groovy script:
def fileList = []
File theInfoName = new File("D:\\SOAP")
theInfoName.eachFile { file ->
if (file.isFile() && file.name.endsWith('.txt')) {
fileList.add(file)
}
}
log.info fileList
//context.put('fileList', fileList)
Here is my request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://www.webserviceX.NET">
<soapenv:Header/>
<soapenv:Body>
${=new File("D:\\SOAP\\" + (context.get('fileList')).last()).text}
</soapenv:Body>
</soapenv:Envelope>
but when I see in request messageExchangeResults it is showing:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://www.webserviceX.NET">
<soapenv:Header/>
<soapenv:Body>
Cannot invoke method last() on null object
</soapenv:Body>
</soapenv:Envelope>

Invalid Soap Call

Why doesn't this soap call work for this URL ?
http://services.aonaware.com/DictService/DictService.asmx?op=Define
<v:Envelope xmlns:i="http://www.w3.org/1999/XMLSchema-instance" xmlns:d="http://www.w3.org/1999/XMLSchema" xmlns:c="http://schemas.xmlsoap.org/soap/encoding/" xmlns:v="http://schemas.xmlsoap.org/soap/envelope/">
<v:Header />
<v:Body>
<Define xmlns="http://tempuri.org/" id="o0" c:root="1">
<word i:type="d:string">Name</word>
</Define>
</v:Body>
</v:Envelope>
But this one does
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://services.aonaware.com/webservices/">
<soapenv:Header/>
<soapenv:Body>
<web:Define>
<!--Optional:-->
<web:word>Test</web:word>
</web:Define>
</soapenv:Body>
</soapenv:Envelope>
Because they are different: not only in content but also in namespace definition, to correct the first one you've to atleast use the correct namespace so use http://services.aonaware.com/webservices/ for your <Define> element as you do in the second one:
<v:Envelope xmlns:i="http://www.w3.org/1999/XMLSchema-instance" xmlns:d="http://www.w3.org/1999/XMLSchema" xmlns:c="http://schemas.xmlsoap.org/soap/encoding/" xmlns:v="http://schemas.xmlsoap.org/soap/envelope/">
<v:Header />
<v:Body>
<Define xmlns="http://services.aonaware.com/webservices/" id="o0" c:root="1">
<word i:type="d:string">Name</word>
</Define>
</v:Body>
</v:Envelope>
Then make sure also that id an c:root are valid attributes in your xsd for <Definition> and i:type it's a correct one for <word>.
EDIT
I invoke http://services.aonaware.com/DictService/DictService.asmx with SOAPUI using my corrected request and it response correctly:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<DefineResponse xmlns="http://services.aonaware.com/webservices/">
<DefineResult>
<Word>Name</Word>
<Definitions>
<Definition>
<Word>Name</Word>
<Dictionary>
<Id>gcide</Id>
<Name>The Collaborative International Dictionary of English v.0.44</Name>
</Dictionary>
<WordDefinition>Name \Name\ (n[=a]m), n. [AS. nama; akin to D. naam, OS. & OHG.
...
[1913 Webster]</WordDefinition>
</Definition>
<Definition>
<Word>Name</Word>
<Dictionary>
<Id>gcide</Id>
<Name>The Collaborative International Dictionary of English v.0.44</Name>
</Dictionary>
<WordDefinition>Name \Name\ (n[=a]m), v. t. [imp. & p. p. {Named} (n[=a]md); p.
...
</WordDefinition>
</Definition>
</Definitions>
</DefineResult>
</DefineResponse>
</soap:Body>
</soap:Envelope>
Hope this helps,

How can I input array using SOAPUI?

Below is the WSDL format for customerNames.
<xsd:element name="CustomersNames" minOccurs="0" maxOccurs="unbounded" type="xsd:string"/>
Please Advice that how can i pass input to test soap request using SOAPUI.
<CustomersNames>--inpuhere--</CustomersNames>
Try to pass Customer name like below.
<CustomersNames>Andrew</CustomersNames>
<CustomersNames>Mohan</CustomersNames>
Try this
<!--Zero or more repetitions:-->
<arg0>5401</arg0>
<arg0>5401</arg0>
<!--Zero or more repetitions:-->
<arg1>0904</arg1>
<arg1>0904</arg1>
<!--Zero or more repetitions:-->
<arg2>20150101</arg2>
<arg2>20150101</arg2>
<!--Zero or more repetitions:-->
<arg3>20170101</arg3>
<arg3>20170101</arg3>
I am getting data like this:
public ArrayList<String> method (List<String> A,
List<String> B,
List<String> C,
List<String> D) {
It works for me!