javaopensamlws-trust

Create SAML 2.0 assertion by existing element in OpenSAML


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?


Solution

  • 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();