How can I receive and verify WS-Federation tokens in python/django? - python

I am trying to implement an assertion consumer for signed WS-Federation tokens as part of a SSO system. I know that simplesamlphp has (undocumented) ws-fed support, but I'm using a Django stack. It looks like djangosaml2 pysaml2 doesn't support the WS-Federation specification as they expect XML with a 'Response' root node, and not a 'RequestSecurityTokenResponseCollection' root node.
Has anyone run into this before? Is there a python library out there that can help me? I'm tempted just to roll my own consumer, but I'm afraid I might slip up and create a security vulnerability due to my lack of X509 and xml knowledge.
Thanks!

I use django-auth-adfs for adfs authentication. I'm not sure how WS-Federation fits in the mix in a Python application, however, if you are authenticating to ADFS, this library does a decent job.

Related

Package to build custom client to consume an API in Python based on a configuration file?

I am new to working with APIs in general and am writing code in python that needs to consume/interact with an API someone else has set up. I was wondering if there is any package out there that would build some sort of custom client class to interact with an API given a file outlining the API in some way (like a json or something where each available endpoint and http verb could be outlined in terms of stuff like allowed payload json schema for posts, general params allowed and their types, expected response json schema, the header key/value for a business verb, etc.). It would be helpful if I could have one master file outlining the endpoints available and then some package uses that to generate a client class we can use to consume the API as described.
In my googling most API packages I have found in python are much more focused on the generation of APIs but this isn't what I want.
Basically I believe you are looking for the built in requests package.
response = requests.get(f'{base_url}{endpoint}',
params={'foo': self.bar,
'foo_2':self.bar_2},
headers={'X-Api-Key': secret}
)
And from here, you can build you own class, pass it to a dataframe or whatever.
In the requests package is basically everything you need. Status handling, exception handling everything you need.
Please check the docs.
https://pypi.org/project/requests/

Protobuf how to use Any type with homebrew proto message

I'm currently building a python gRPC server that serializes tons of different proto messages into json to store them into a no-sql db. I'd like to simplify extension of this server such that we can add new types without rewriting the gRPC server and redeploying. Ideally, we would like to define a new message, put it in a proto file and update only the client. The server should expect any type at first but knows a .proto file or folder where to look for when it comes to serializing/deserializing.
I've read about the Any type and I'm exploring whether this is my way to do this. There is some documentation on it but very few examples to work with. One thing that I don't quite get is how to store/retrieve the type of an "Any" field.
All documentation use https as protocol for the type of an Any field (e.g. type.googleapis.com/google.protobuf.Duration). This is also the default. How would it look like if I use the local file system? How would I store this in the proto message on the client side?
How can I retrieve the type on the server side?
Where can I find a similar example?
Apologies, this is only a partial answer.
I've recently begun using Any in a project and can provide some perspective. I have a similar (albeit simpler) requirement to what you outline. Enveloped message content but, in my case, clients are required to ship a descriptor to the server and identify a specific method to help it (un)marshal etc.
I've been using Google's new Golang APIv2 and only familiar with it from Golang and Rust (not Python). The documentation is lacking but the Golang documents will hopefully help:
anypb
protoregistry
I too struggled with understanding the concept (implementation) of the global registry and so I hacked the above solution. The incoming message metadata provides sufficient context to the server that it can construct the message type and marshal the bytes into it.

WSHttpBinding: Entropy.BinarySecret role in message encryption

I am writing a simple SOAP client application in Python.
WSDL file can be found here: https://clients.nationalmailing.com.au/ServiceTest/OrderService.svc?wsdl
Unfortunately the server declared usage of wsHttpBinding in its WSDL file and I had to learn how many troubles it brings to not-.NET developers.
I have working C# code (and it is pretty simple there) and used Fiddler to capture the traffic and analyze messages. Now I know the structure to follow. Client sends 2 subsequental messages.
I managed to create and send first request and receive a response from the server. BUT second request is a way more complex. I have found a library signxml which helped me to create <Signature> structure with all the fields that should present (as per captured traffic).
But the server continues to answer with "Error 500: An error occurred when verifying security for the message."
I realized that in the first message I put just random values for the following structure:
<s:Body>
<trust:RequestSecurityToken xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
<trust:TokenType>http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512/sct</trust:TokenType>
<trust:RequestType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue</trust:RequestType>
<trust:Entropy>
<trust:BinarySecret
u:Id="uuid-0649fd7a-9ae2-4f9f-964c-e3aa5d68e8cd-1"
Type="http://docs.oasis-open.org/ws-sx/ws-trust/200512/Nonce">h/MaeQVSL5Br30Hnt/SAl274flYfZVZyx2Fri9zNuEY=</trust:BinarySecret>
</trust:Entropy>
<trust:KeySize>256</trust:KeySize>
</trust:RequestSecurityToken>
</s:Body>
The value of BinarySecret is just a random string encoded with Base64. I think this should be an issue on this stage. I also do not use the same parameters from server's response.
Could anyone explain how should I use Entropy.BinarySecret - should it take part in the calculations of Signature and how it is used?
Answering my own question. Yes, the issue was in improper usage of Entropy parameter.
To sign the message you need to generate a key, it consists of two parts (client entropy and server's entropy). They get combined with P_SHA1 algorithm into a key.
To anyone who find this post in the future: for Python have a look on signxml library and section 4 of ws-trust spec.

softlayer API missing serverRoom

I'm seeing an issue where the SoftLayer API is missing the serverRoom field for over 75% of our servers. I've confirmed this using both their python and ruby libraries (https://softlayer-api-python-client.readthedocs.org/en/latest/api/managers/hardware/#SoftLayer.managers.hardware.HardwareManager.list_hardware and https://softlayer.github.io/ruby/server_locate/ respectively). Note that the ruby code I'm running is simply one of their published examples.
It seems like SoftLayer has a naming convention of creating FQDN like [dataCenter].[serverRoom].[rackNumber].[slotNumber]. I'm not sure if it is just another indicator of the problem or helpful in troubleshooting the root cause, but the servers that are missing serverRoom seem to be named incorrectly by SoftLayer, according to what appears to be SoftLayer's naming convention. They are named [dataCenter].[rackNumber].[slotNumber], notably missing serverRoom.
Basically it looks like their database (which I assume is backing their API) is just missing the serverRoom for most of the hosts, or they named most of our hosts incorrectly and the database can't account for it, so the info is missing when I call their API. Does anyone have a similar experience where SoftLayer perhaps named things wrong, or forgot to do this data entry, or are there some other/different API calls I should be making beyond what SoftLayer themselves recommend?
I tried to verify and reproduce the issue that you mentioned, but I couldn't. please Submit a ticket with all the information that you can provide to verify and isolate this issue.
SoftLayer support confirmed that there was a some sort of block on hidden sites where this info wasn't displayed via their API. Thanks to #ruber-cuellar was who said something similar in one of his comments, but I disagree that "There is not an issue." From my perspective there definitely was an issue that they (SoftLayer support) needed to resolve on their end before their example API calls started showing us all the info. Special thanks to ALLmightySPIFF on #softlayer who was able to repro the issue for me and provided a realtime response.

Python SOAP document handling

I've been trying to use suds for Python to call a SOAP WSDL. I just need to call the service programmatically and write the output XML document. However suds automatically parses this data into it's own pythonic data format. I've been looking through the examples and the documentation, but I can't seem to find a way to return the XML document that the SOAP service gives me.
Is there an easy way to do this I'm overlooking? Is there an easier way to do this in Python than suds?
At this early stage in suds development, the easiest way to get to the raw XML content is not what one would expect.
The examples on the site show us with something like this:
client = Client(url)
result = client.service.Invoke(subm)
however, the result is a pre-parsed object that is great for access by Python, but not for XML document access. Fortunately the Client object still has the original SOAP message received stored.
result = client.last_received()
print result
Will give you the actual SOAP message received back.
You could take a look at a library such as soaplib: its a really nice way to consume (and serve) SOAP webservices in Python. The latest version has some code to dynamically generate Python bindings either dynamically (at runtime) or statically (run a script against some WSDL).
[disclaimer: I'm the maintainer of the project! - I didn't write the bulk of it though]

Categories

Resources