Thursday, 10 June 2010

Python SAML 2.0 Released

I've been working on a Python implementation of SAML 2.0 for some months now and recently pushed this to the Python repository PyPI.  SAML is an important tool in the Earth System Grid Security architecture that I've been working on and the NERC DataGrid security framework which predates it. It's used for attribute retrieval and authorisation decision queries.  The code focusses on these aspects of the specification.  This example illustrates an client attribute query to an Attribute Authority:


from ndg.saml.saml2.core import (AttributeQuery, SAMLVersion, Issuer, Subject,
                                 NameID, Attribute, XSStringAttributeValue)
from uuid import uuid4
from datetime import datetime

attributeQuery = AttributeQuery()
attributeQuery.version = SAMLVersion(SAMLVersion.VERSION_20)
attributeQuery.id = str(uuid4())
attributeQuery.issueInstant = datetime.utcnow()

attributeQuery.issuer = Issuer()
attributeQuery.issuer.format = Issuer.X509_SUBJECT
attributeQuery.issuer.value = '/O=NDG/OU=BADC/CN=PolicyInformationPoint'
                
attributeQuery.subject = Subject()  
attributeQuery.subject.nameID = NameID()
attributeQuery.subject.nameID.format = NameID.X509_SUBJECT
attributeQuery.subject.nameID.value = '/O=NDG/OU=BADC/CN=PhilipKershaw'

# special case handling for 'LastName' attribute
emailAddressAttribute = Attribute()
emailAddressAttribute.name = "urn:esg:email:address"
emailAddressAttribute.nameFormat = "%s#%s" % (
                                XSStringAttributeValue.TYPE_NAME.namespaceURI,
                                XSStringAttributeValue.TYPE_NAME.localPart)

emailAddress = XSStringAttributeValue()
emailAddress.value = 'pjk@somewhere.ac.uk'
emailAddressAttribute.attributeValues.append(emailAddress)

attributeQuery.attributes.append(emailAddressAttribute)

# Convert to ElementTree representation
from ndg.saml.xml.etree import AttributeQueryElementTree, prettyPrint

elem = AttributeQueryElementTree.toXML(attributeQuery)

# Serialise as string
xmlOut = prettyPrint(elem)
print(xmlOut)



The XML representation and serialisation is independent of the core code. The ndg.saml.xml.etree ElementTree representation comes with the rest of the code but it would be straightforward to add an adaptor for another Python XML package such as 4Suite-XML.

Here's the serialised output:


<samlp:attributequery id="1c15e748-0f74-41f1-848c-1fbdfeef2a06" issueinstant="2010-06-01T13:19:50.690263Z" version="2.0" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
    <saml:issuer format="urn:oasis:names:tc:SAML:1.1:nameid-format:x509SubjectName" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">/O=NDG/OU=BADC/CN=PolicyInformationPoint</saml:issuer>
    <saml:subject xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
        <saml:nameid format="urn:oasis:names:tc:SAML:1.1:nameid-format:x509SubjectName">/O=NDG/OU=BADC/CN=PhilipKershaw</saml:nameid>
    </saml:subject>
    <saml:attribute name="urn:esg:email:address" nameformat="http://www.w3.org/2001/XMLSchema#string" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
        <saml:attributevalue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">pjk@somewhere.ac.uk</saml:attributevalue>
    </saml:attribute>
</samlp:attributequery>


More to follow - including client/server SOAP bindings - as I migrate the SAML specific code out of the NERC DataGrid security package.

No comments: