Creating SAML Objects from an XML Source
Creating SAML objects from an XML source is done through a process known as unmarshalling which operates on DOM Elements. The OpenSAML 2 library contains many unmarshallers and the appropriate one is selected based off of either the XML Schema type of the Element to be unmarshalled or the Element's QName (a tuple representing the namespace the element is in and the element's name).
- Parse the XML into a DOM element.
- Retrieve the unmarshaller factory using
- Get an unmarshaller for the element using the
org.opensaml.xml.io.UnmarshallerFactory#getUnmarshaller(Element) method. The element argument is the root element from which you wish to begin unmarshalling. This is normally the document element if you're unmarshalling data from a file.
- Invoke the
unmarshall(Element) method on the returned
Unmarshaller using the same element argument as in the previous step.
The following example shows the parsing and unmarshalling of a SAML 2 metadata document. The try/catch code has been omitted here for readability. The complete code can be found in
org.opensaml.saml2.metadata.MetadataTest#testInCommonUnmarshall() method in the OpenSAML 2.0 test source code.
String inCommonMDFile = "/data/org/opensaml/saml2/metadata/InCommon-metadata.xml";
// Initialize the library
// Get parser pool manager
BasicParserPool ppMgr = new BasicParserPool();
// Parse metadata file
InputStream in = MetadataTest.class.getResourceAsStream(inCommonMDFile);
Document inCommonMDDoc = ppMgr.parse(in);
Element metadataRoot = inCommonMDDoc.getDocumentElement();
// Get apropriate unmarshaller
UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory();
Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(metadataRoot);
// Unmarshall using the document root element, an EntitiesDescriptor in this case
EntitiesDescriptor inCommonMD = (EntitiesDescriptor) unmarshaller.unmarshall(metadataRoot);
Additional Unmarshalling Information
- When fetching an unmarshaller based on an element the factory first checks to see if the element has a schema type specified by an
xsi:type attribute. If it does, the factory attempts to lookup an unmarshaller for that schema type. If the element does not have a specified schema type, or no unmarshaller is registered for that schema type, the factory uses the element's name.
- The unmarshaller factory can also retrieve unmarshallers based on a
QName argument using the
getUnmarshaller(QName) method. If this method is used the two step check mentioned above is not used, instead it is up to the developer to know, or care, whether the given QName represents an element's name or its schema type.
- Interfaces for the SAMLObjects contain constants that represent its default element name and schema type. These can be useful for retrieve unmarshallers by QName.
- All SAMLObjects produced through unmarshalling contain a reference to their DOM. This cached DOM will be destroyed if the SAMLObject is changed in some way (e.g. a child element is removed) and developers should never attempt to directly manipulate it. It does, however, make the marshalling of objects significantly faster and allows things like the digital signatures and encrypted information to be preserved, both of which make dealing with SAML inside of SOAP much nicer.