Create SAML 2.0 assertion by existing element in OpenSAML

900 Views Asked by At

I am trying to create an SAML 2.0 assertion with OpenSAML using an existing assertion element for a token renewal process.

 // Obtain the token
            Token tk = tkStorage.getToken(data.getTokenId());

            OMElement assertionOMElement = tk.getToken();
            int samlRstversion = data.getSamlRstVersion(); 
if(samlRstversion == 2) {
                    DefaultBootstrap.bootstrap();
                    UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory();
                    Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller((Element)assertionOMElement);
                    Element x1 = (Element)assertionOMElement;
                    Assertion samlAssertion = (Assertion) unmarshaller
                            .unmarshall(x1);
    //Add conditions to the assertion
}

I'm getting two errors.

  1. When the DefaultBootstrap.bootstrap(); is used, it throws an exception java.lang.UnsupportedOperationException: This parser does not support specification "null" version "null"
  2. When DefaultBootstrap.bootstrap() is removed it throws at Assertion samlAssertion = (Assertion) unmarshaller.unmarshall(x1);

Is there something that I have missed?

2

There are 2 best solutions below

0
On BEST ANSWER

There were two errors which caused the exception. Of course the bootsrap() had to be done in order to continue with marshalling or unmarshalling.

  1. In a previous line of the code the DOM implementation was changing to DOOM. DocumentBuilderFactoryImpl.setDOOMRequired(true); Even though it was deprecated the code was using it. So before do bootstrap() it had to be set to false since the underlying JAXB implementation uses the DOM.

  2. Also, casting OMElement assertionOMElement to Element threw this exception. org.w3c.dom.DOMException: NAMESPACE_ERR: An attempt is made to create or change an object in a way which is incorrect with regard to namespaces.

Solution was to convert the OMElement to String and then build the Document from it and get the DocumentElement

String s = assertionOMElement.toString();
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
DocumentBuilder docBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = docBuilder.parse(new ByteArrayInputStream(s.trim().getBytes()));
Element element = document.getDocumentElement();
0
On

Firstly, you always have to run the bootstrap or else you get errors.

It seams like the first error is because you have a too old implementation of JAXP https://lists.internet2.edu/sympa/arc/mace-opensaml-users/2010-01/msg00015.html

The OpenSAML team suggests using Apache Xerces or Xalan.