Writing SAML Objects to XML
Once you have SAMLObjects writing them to XML is done through a marshalling process. The OpenSAML 2 library contains many marshallers and the appropriate one is selected based off of either the XML Schema type of the object to be marshalled or the Object's QName (a tuple representing the namespace the element is in and the element's name).
- Retrieve the marshaller factory using
- Retrieve a marshaller for the SAMLObject using the
org.opensaml.xml.io.UnmarshallerFactory#getMarshaller(XMLObject) where the argument is the SAML object you wish to marshall.
- Invoke the
marshall(XMLObject) method on the returned
org.opensaml.xml.io.Marshaller, again taking the SAMLObject as the argument.
The following example shows the creation of a SAML 2 Subject, setting some information, and then marshalling it. The try/catch code has been omitted here for readability.
// Get the builder factory
XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory();
// Get the subject builder based on the subject element name
SubjectBuilder builder = (SubjectBuilder ) builderFactory.getBuilder(Subject.DEFAULT_ELEMENT_NAME);
// Create the subject
Subject subject = builder.buildObject();
// Added an NameID and two SubjectConfirmation items - creation of these items is not shown
// Get the marshaller factory
MarshallerFactory marshallerFactory = Configuration.getMarshallerFactory();
// Get the Subject marshaller
Marshaller marshaller = marshallerFactory.getMarshaller(subject);
// Marshall the Subject
Element subjectElement = marshaller.marshall(subject);
Additional Marshalling Information
Marshallers provide two addition marshalling methods.
marshall(XMLObject, Document) can be used to marshall the given SAMLObject while ensuring all the created elements are owned by the given document. This method also plants the DOM element representation of the given SAMLObject as the root (or document) element of the given Document.
marshall(XMLObject, Element) marshalls the given SAMLObject and appends the created DOM tree as a child of the given Element. All elements created in this process are owned by the same document that owns the given Element. If the given SAMLObject is a node within a larger SAMLObject tree (i.e.
getParent() returns something other than null) and has a cached DOM then its parent's cached DOM will be invalidated because the SAMLObject's DOM will be adopted into a new tree. During this adoption process all the visible namespaces used by the SAMLObject or any of its descendants will be added to the SAMLObject or the first descendant that uses it. This ensures that namespace declarations are kept when the DOM Element resulting from the marshall is added the given parent Element.
Caution should be taken when using either of these marshalling methods. The first method can result in problems resolving IDs, namespace URIs, and prefixes, and tree navigability because it may change the root element of your document and leave other nodes orphaned. The second method, while being very useful for tasks such as taking a SAML statement and putting it within a SOAP message, will remove the SAMLObjects cached DOM from its prior tree and add it to the new one. This could lead to unexpected problems if your application is not aware of this.