I'm trying to get a response from a wsdl url using Zeep
A username, password, nonce (PasswordDigest), timestamp and headers are required. It all works fine in SoapUI but I can't make it work with Zeep, I get the error from the server:
Fault: A security error was encountered when verifying the message
And I guess the issue comes from the headers but I can't find the right way to add them.
Here's what it looks like in SoapUI
Here's a request example provided by the web service documentation:
<soapenv:Envelope xmlns:soapenv=***schemas.xmlsoap.org/soap/envelope/
xmlns:mes="***economie.fgov.be/KBOpub/webservices/v1/messages"
xmlns:dat="***economie.fgov.be/KBOpub/webservices/v1/datamodel">
<soapenv:Header>
<wsse:Security>
<wsu:Timestamp>
<wsu:Created>2009-09-07T11:27:10.748Z</wsu:Created>
<wsu:Expires>2009-09-07T11:32:10.748Z</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken>
<wsse:Username>userid</wsse:Username>
<wsse:Password>x3+DQlYgeVm3BAkobZivkDJ13zo=</wsse:Password>
<wsse:Nonce>ENp2ha7j2Ar9cvWQeUybTQ==</wsse:Nonce>
<wsu:Created>2009-09-07T11:27:10.716Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
<mes:RequestContext>
<mes:Id>c1576d0a-e762-40fe-abf9-ec3f2102650b</mes:Id>
<mes:Language>fr</mes:Language>
</mes:RequestContext>
</soapenv:Header>
<soapenv:Corps>
<mes:ReadEnterpriseRequest>
<dat:EnterpriseNumber>0314595348</dat:EnterpriseNumber>
</mes:ReadEnterpriseRequest>
</soapenv:Corps>
</soapenv:Envelope>
What I've tried based on answers found on other questions:
from zeep.wsse.username import UsernameToken
import datetime
from zeep.wsse.utils import WSU
from zeep.xsd import Element, ComplexType, String, Sequence
wsdl_url = '***bopub.economie.fgov.be/kbopubws110000/services/wsKBOPub?wsdl'
username = '***'
password = '******'
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:%S.%fZ")),
WSU.Expires(expires_datetime.strftime("%Y-%m-%dT%H:%M:%S.%fZ"))]
timestamp_token.extend(timestamp_elements)
user_name_token = UsernameToken(username, password, timestamp_token=timestamp_token, use_digest=True)
client = Client(wsdl_url, wsse=user_name_token)
client.set_ns_prefix('mes', "***economie.fgov.be/kbopub/webservices/v1/messages")
headerQ = Element('{***schemas.xmlsoap.org/soap/envelope.xsd}Header', ComplexType([
Element('{***economie.fgov.be/kbopub/webservices/v1/messages.xsd}RequestContext', ComplexType(
Sequence([
Element('{***economie.fgov.be/kbopub/webservices/v1/messages.xsd}Id', String()),
Element('{***economie.fgov.be/kbopub/webservices/v1/messages.xsd}Language', String())
]))
)
]))
header_value = headerQ({'Id': 'whatever', 'Language': 'fr'})
client.set_default_soapheaders([header_value])
client.service.ReadEnterprise(EnterpriseNumber='0314595348')
And I always get the same security error coming from the server
Thanks
I was able to find a solution to my own question, I'll explain how I found it as I hope it may help someone.
I first checked the http log in SoapUI to see what the request was supposed to look like:
then I compared with what was sent using the HistoryPlugin:
And could easily see what needed to be changed. Eventually my code looks like this: