mvantellingen / python-zeep

A Python SOAP client
http://docs.python-zeep.org
Other
1.88k stars 585 forks source link

Optionally remove "urn" prefix from wsa:MessageID #975

Open bastbnl opened 5 years ago

bastbnl commented 5 years ago

Hi,

I'm trying to connect an application to the Dutch Chamber of Commerce (KvK) dataservice using python 3.7.3 and zeep==3.4.0. This appears to be a bit of a pain.

The wsdl for this service is available via http://schemas.kvk.nl/contracts/kvk/dataservice/catalogus/2015/02/. No problems there yet.

wsa is added automatically, probably due to data found in the wsdl. The wsa headers are added twice when I add the WsAddressingPlugin via the plugins parameter at initialization of the Client instance. I'll try to add a reproducer later on.

There's a requirement in the docs saying the service is unable to process messages that contain a MessageID which is prefixed by urn. I think a lot of developers would be happier when the service would be able to process messages containing that prefix instead of documenting this issue, but that's out of my control. Here's an excerpt in Dutch, but I'm guessing that's not an issue for you ;)

LET OP: sommige IDE tooling zoals bijvoorbeeld Microsoft Visual Studio voegt “urn:” voor “uuid:”. De Handelsregister Dataservice controles zullen een request met deze syntax afwijzen! (https://www.kvk.nl/sites/aansluitendataservice/index.html#/webservice-werkingsprincipes)

Is there a way to remove the urn prefix from the MessageID? Do I need to override the plugin somewhere?

bastbnl commented 5 years ago

Reproducer for the double wsa headers for python 3:

from lxml import etree

from requests import Session

from zeep import Client, Settings
from zeep.transports import Transport
from zeep.wsa import WsAddressingPlugin

def reproducer_for_double_wsa_headers():
    soap_client_settings = Settings(
        strict=False,
    )
    soap_request_session = Session()
    soap_client = Client(
        'http://schemas.kvk.nl/contracts/kvk/dataservice/catalogus/2015/02/KVK-KvKDataservice.wsdl',
        settings=soap_client_settings,
        transport=Transport(
            timeout=10,
            operation_timeout=10,
            session=soap_request_session,
        ),
        plugins=[
            WsAddressingPlugin(),
        ],
    )
    soap_message = soap_client.create_message(
        soap_client.service,
        'ophalenInschrijving',
        kvkNummer='11111111',
        klantreferentie='github-974', 
    )
    print(
        etree.tostring(
            soap_message,
            pretty_print=True,
            xml_declaration=True,
            encoding='utf-8',
        ).decode()
    )

Expected output:

<?xml version='1.0' encoding='utf-8'?>
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
  <soap-env:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
    <wsa:Action>http://es.kvk.nl/ophalenInschrijving</wsa:Action>
    <wsa:MessageID>uuid:3165ca25-b3f4-4619-9a50-00fdbb7afa50</wsa:MessageID>
    <wsa:To>https://example.com/</wsa:To>
  </soap-env:Header>
  <soap-env:Body>
    <ns0:ophalenInschrijvingRequest xmlns:ns0="http://schemas.kvk.nl/schemas/hrip/dataservice/2015/02">
      <ns0:klantreferentie>github-974</ns0:klantreferentie>
      <ns0:kvkNummer>11111111</ns0:kvkNummer>
    </ns0:ophalenInschrijvingRequest>
  </soap-env:Body>
</soap-env:Envelope>

Actual output:

<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
  <soap-env:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
    <wsa:Action>http://es.kvk.nl/ophalenInschrijving</wsa:Action>
    <wsa:MessageID>uuid:686ab93e-9715-4719-a839-a1895dcb70ef</wsa:MessageID>
    <wsa:To>https://example.com/</wsa:To>
    <wsa:Action>http://es.kvk.nl/ophalenInschrijving</wsa:Action>
    <wsa:MessageID>uuid:5759ba8f-4ebe-4529-b540-bc4c6175f406</wsa:MessageID>
    <wsa:To>https://example.com/</wsa:To>
  </soap-env:Header>
  <soap-env:Body>
    <ns0:ophalenInschrijvingRequest xmlns:ns0="http://schemas.kvk.nl/schemas/hrip/dataservice/2015/02">
      <ns0:klantreferentie>github-974</ns0:klantreferentie>
      <ns0:kvkNummer>11111111</ns0:kvkNummer>
    </ns0:ophalenInschrijvingRequest>
  </soap-env:Body>
</soap-env:Envelope>
bastbnl commented 5 years ago

It gets a bit more confusing when you attempt to override via _soapheaders and use the plugins. You'll end up with additional headers found in _soapheaders.

renevdkooi commented 5 years ago

@bastbnl were you able to fix this at any point? I'm trying to connect to the same service, but I'm not even getting a response form the service.

bastbnl commented 5 years ago

@renevdkooi I'm able to connect to the preprod environment and retrieve data, but not using zeep. Happy to discuss how I did it.

renevdkooi commented 5 years ago

Would love to see how you did it or put me in the right direction. I tried with PHP, but got nothing working. So I tried moving to python and using this ZEEP, but don't seem to get any data.

Any way to contact you?

bastbnl commented 5 years ago

Sure, contact me via zeep-github@brwnppr.com. It'll take me some time to respond though.

zeyadmbk commented 4 years ago

Hi @bastbnl I'm working on a project that involves KvK dataservices and I'm using PHP. Although I'm able to connect but I'm struggling to retrieve any data and I always get "Not Authorized". I was able to get the data using SoapUI but not with PHP. So, I was thinking to use another language like Python and after researching I stumbled upon this post. So I'm wondering how were you able to solve this.

renevdkooi commented 4 years ago

I was actually able to get this to work under php. It was easier than I thought. You can use normal soap requests, but you need to play with the security.

zeyadmbk commented 4 years ago

@renevdkooi Thanks a lot for your feedback. I agree I reached out to KvK support and they said it something has to do with security and message signing but they cannot see any issue with the SOAP XML. Unfortunately they cannot help further with PHP. I've been playing around for days with the security but without any success. Would it possible if you can share some code sample that worked for you?

bastbnl commented 4 years ago

@zeyadmbk just letting you know I didn't use PHP, so I'm afraid I can't help with PHP code. I used the requests module to send the message because I was unable to find a way to provide the CSA using zeep.

Make sure you're signing Body, To, MessageID, Action and Timestamp in the message you're sending. Also make sure you're using http://www.w3.org/2005/08/addressing and not a newer version.

renevdkooi commented 4 years ago

@zeyadmbk You can contact me at renevdkooi@hotmail.com

Merinorus commented 1 year ago

Hi, I encountered the same problem. Will make a PR on this one! Feel free to review it.

gk965 commented 7 months ago

Hi, this was already a while ago but I am trying to test the KvK dataservice using Postman and running into the authorization issue. A couple people in this thread mentioned they managed to figure it out so is it possible for me to contact someone to get some help?