SOAP API Get Cookie - python

I'm using a SOAP API to get an authentication key with a cookie that is suppose to be returned.
from zeep import Client
client = Client("AuthenticationService.xml")
result = client.service.ValidateUser(username, password, "")
result
However with the result, I am getting a Boolean of True but no Cookie that contains the authentication key.
From the below picture, you can see that the same request using SoapUI returns a cookie. I'm wondering how I can do this in Python.

To be able to handle cookie, we must use requests.Session for the transport.
So a simple use case would look like this for you:
from zeep import Client
from requests import Session
from zeep.transports import Transport
session = Session()
# disable TLS verification
session.verify = False
transport = Transport(session=session)
client = Client("AuthenticationService.xml", transport=transport)
result = client.service.ValidateUser(username, password, "")
# then check cookie
client.transport.session.cookies
hope this helps.

Related

Flask server side implemetation for certificate based Auth

I am trying to implement server side code to authenticate the client using certificate and Authorize based on the Groups associated in certificate.
The client side code goes like this:
import json
import requests
clientCrt = "cc.crt"
clientKey = "ck.key"
url = "https://example.com/api"
payload = { "someId": "myID" }
certServer = 'cs.crt'
headers = {'content-type': 'application/json'}
r = requests.post(url, data=json.dumps(payload), verify=certServer,
headers=headers, cert=(clientCrt, clientKey))
print(r.status_code)
print(r.json())
I want to have a corresponding server side implementation specifically to check whether request should be honoured based on the clientCrt
Can someone share how i can access the clientCrt on server side and extract the fields of certificate.
Note: I am not looking for mutual TLS Auth, I am interested in Service Authentication and Authorization
Mutual TLS is not configured on a default wsgi serving connection object. This needs to be configured. See this page for more details - https://www.ajg.id.au/2018/01/01/mutual-tls-with-python-flask-and-werkzeug/. Once you have the connection object handy, you can use request.environ['peercert'].get_subject() to get the details of the client cert.
Better way to handle this is by delegating it to Gunicorn or nginx proxy. See https://eugene.kovalev.systems/posts/flask-client-side-tls-authentication/ for more examples

Can you use Async Zeep to call a SOAP service behind Basic Auth?

I'm trying to turn a previously working synchronous usage of the Zeep library into the Async version of this. On a request to the WSDL, the transport will always return a 404.
The following is the sync implementation and is working as intended.
session = Session()
session.auth = HTTPBasicAuth(username, password)
transport = Transport(session=session)
return Client(config_url, transport=transport)
However, when I change this to an async implementation (using httpx) it will return a Transport Error. The only message in this transport error is 401.
http_client = httpx.Client()
http_client.auth = (username, password)
http_client.verify = True
transport = AsyncTransport(session=http_client)
return AsyncClient(config_url, transport=transport)
Am I using async Zeep correctly? According to the docs it should work like this
Ok, Apparently the interface isn't exactly the same. To instantiate a AsyncClient for zeep with basic auth, you'll need to create a Sync and Async client.
This is because zeep fetches the WSDL in a synchronous manner, and then executes the requests asynchronously. This means that the wsdl_client must be synchronous and the client must be ansynchronous!
async_client = httpx.AsyncClient(
auth=(username, password),
verify=True
)
wsdl_client = httpx.Client(
auth=(username, password),
verify=True
)
transport = AsyncTransport(client=async_client, wsdl_client=wsdl_client)
return AsyncClient(config_url, transport=transport)
With this, we can now await all service requests as described in the docs.

Python Zeep is throwing unkown fault for soap request

I am new to using the framework zeep. I am trying to send a SOAP request . But I get the below incorrect data. I need to get the response in xml or csv format.
<Element {http://schemas.xmlsoap.org/soap/envelope/}Envelope at 0x7fabdc9ea888>
With the wsdl, I am able to fetch the correct output using SoapUI tool.
from requests import Session
from zeep import Client
from zeep.transports import Transport
from requests.auth import AuthBase, HTTPBasicAuth
import datetime
wsdl = 'http://XX.XXX.XX.XX:ZZZZ/TL/IM?wsdl'
session = Session()
session.auth = SymantecAuth('user','password', "http://XX.XXX.XX.XXX")
session.verify = False
transport = Transport(session=session)
client = Client(wsdl=wsdl, transport=transport)
request_data = {"platforms": "test", "platid": {"ID": "QI4552"}}
results=client.create_message(client.service, 'RetrieveID', request_data)
print(results)
Since you are creating the message, print(results) is just showing the message object created.
Instead this should work to print the message on screen:
from lxml import etree
# Your code follows here
results=client.create_message(client.service, 'RetrieveID', request_data)
# this will print the message to be sent to Soap service.
print(etree.tostring(results, pretty_print=True))
If you want to see the response of the RetrieveID operation. then do this instead (Provided this method is bound on 1st available binding):
response = client.service.RetrieveID(**request_data)
print(response)
Let us know if it doesn't work.

Preemptive authentication with Zeep and requests

I need to talk to a SOAP server which requires "preemptive authentication" (it uses BasicAuth).
I have no idea of how to configure my zeep client to make it behave accordingly.
As it says here, the SoapUI tool can be configured to use "preemptive authentication"
Can anyone please help me achieve the same? (either configuring zeep or requests)
Here is my code, which is pretty standard:
session = Session()
session.verify = False # ignore certificate
session.auth = HTTPBasicAuth(user, pwd)
transport = Transport(session=session)
client = Client(wsdl, transport=transport)
# ...
response = client.service.Operation(**params)
The above fails authenticating and ends up with an SSL error, which is expected.
Any help is much appreciated. Thank you
In theory, you should be able to do this by creating a session and modifying the headers directly. This way, the header will be sent with the original request instead of using the auth behavior of waiting for a challenge.
import requests
session = requests.Session()
session.headers['Authorization'] = 'Basic ' + <your 64-bit encoded user:pass>
transport = zeep.Transport(session=session)
client = zeep.Client(wsdl=soapURI,transport=transport)

Python "requests" library: HTTP basic authentication for each request

In a Python script I use the "Requests" library with HTTP basic authentication and a custom CA certificate to trust like this:
import requests
response = requests.get(base_url, auth=(username, password), verify=ssl_ca_file)
All requests I need to make have to use these parameters. Is there a "Python" way to set these as default for all requests?
Use Session(). Documentation states:
The Session object allows you to persist certain parameters across
requests.
import requests
s = requests.Session()
s.auth = (username, password)
s.verify = ssl_ca_file
s.get(base_url)

Categories

Resources