I am attempting to consume a web service using Delphi 2010 and Indy. To establish a usable SOAP stream to compare to the one created by my program, I am testing in SOAPUI. I am using a SOAP stream provided by the web service provider which also matches the SOAP stream specified in the WSDL file. I am getting an HTTP 400 (bad request) error from the service.
From what I can find online, it appears that receiving an HTTP 400 error indicates that your SOAP request is malformed and can not be read by the web service. I have tested my SOAP stream using XMLPad and the XML seems to be well formed. I suppose this may mean that something does not match its schema requirement. I will first check the schema description for the password in case that is expected to not be sent as plain text. What else should I be checking to eliminate an HTTP 400 error?
Here is my request (less username and password) in case it helps:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
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:xop="http://www.w3.org/2004/08/xop/include"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://wwww3.org/2001/XMLSchema-instance">
<soap:Header>
<wsa:Action>http://edd.ca.gov/SendTransmission</wsa:Action>
<wsa:MessageID>urn:uuid:5aa788dc-86e1-448b-b085-2d2743cf9f26</wsa:MessageID>
<wsa:ReplyTo>
<wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address>
</wsa:ReplyTo>
<wsa:To>http://fsettestversion.edd.ca.gov/fsetproxy/fsetservice.asmx</wsa:To>
<wsse:Security soap:mustUnderstand="1">
<wsse:UsernameToken wsu:Id="UsernameToken">
<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">O5QWht1bslLCX6KnlEypAA==</wsse:Nonce>
<wsu:Created>2012-02-29T22:32:38.250Z</wsu:Created>
</wsse:UsernameToken>
<wsu:Timestamp wsu:Id="Timestamp-805a7373-335c-43b6-ba21-6596c4848dbf">
<wsu:Created>2012-02-22T15:41:42Z</wsu:Created>
<wsu:Expires>2012-02-22T15:46:42Z</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
</soap:Header>
<soap:Body>
<SendTransmission xmlns="http://edd.ca.gov/">
<SendTransmissionRequest xmlns="http://www.irs.gov/a2a/mef/MeFTransmitterServiceWse.xsd">
<TransmissionDataList>
<Count>1</Count>
<TransmissionData>
<TransmissionId>123456789</TransmissionId>
<ElectronicPostmark>2012-02-22T07:41:42.2502206-08:00</ElectronicPostmark>
</TransmissionData>
</TransmissionDataList>
</SendTransmissionRequest>
<fileBytes>
<xop:Include href="cid:[email protected]"/>
</fileBytes>
</SendTransmission>
</soap:Body>
</soap:Envelope>
There may be something else, but at the moment, I am suspicious of the wsse:UsernameToken. I downloaded the document at http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0.pdf and read it last night. It's written in fairly plain language and I feel like I understand what it is saying but it leaves me with a smaller question than the one I asked originally. This document proposes that you can use a plain text password in this format:
<S11:Envelope xmlns:S11="..." xmlns:wsse="...">
<S11:Header>
...
<wsse:Security>
<wsse:UsernameToken>
<wsse:Username>Zoe</wsse:Username>
<wsse:Password>IloveDogs</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
...
</S11:Header>
...
</S11:Envelope>
Or you can use a password digest. It defines a password digest like this:
Password_Digest = Base64 ( SHA-1 ( nonce + created + password ) )
According to the reference, the format for a password digest would look like this:
<S11:Envelope xmlns:S11="..." xmlns:wsse="..." xmlns:wsu= "...">
<S11:Header>
...
<wsse:Security>
<wsse:UsernameToken>
<wsse:Username>NNK</wsse:Username>
<wsse:Password Type="...#PasswordDigest">
weYI3nXd8LjMNVksCKFV8t3rgHh3Rw==
</wsse:Password>
<wsse:Nonce>WScqanjCEAC4mQoBE07sAQ==</wsse:Nonce>
<wsu:Created>2003-07-16T01:24:32Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
...
</S11:Header>
...
</S11:Envelope>
This is not the format used in the example provided by the web service publisher. The plain text version in the reference does not use a nonce. The example message uses a nonce but calls for a plain text password. It appears to me that the use of a nonce without a password digest does not add any security to the message. It could be any random string of characters if there is no agreement for how it is to be created. Am I missing the point?
I know this must seem like a tedious undertaking, but I am hoping that by providing this here, maybe we can provide a little help to the next person coming along.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With