简体   繁体   English

创建 QName 异常时,Opensaml unmarshallMessage 给出的 opensaml 本地部分不能为“null”

[英]Opensaml unmarshallMessage giving opensaml local part cannot be "null" when creating a QName Exception

I am using Spring SAML , from IDP response I am receiving issuer as an attribute ID, So I wanted to change the response after receiving in spring saml, so I have overridden method unmarshall which will parse the message and changed the xml elements for this purpose. I am using Spring SAML , from IDP response I am receiving issuer as an attribute ID, So I wanted to change the response after receiving in spring saml, so I have overridden method unmarshall which will parse the message and changed the xml elements for this purpose . While doing this if I directly use the Element after parsing to unmarshall it is working but if I do dom manipulation it is giving the below exception.这样做时,如果我在解析解组后直接使用 Element,它正在工作,但如果我进行 dom 操作,则会给出以下异常。 I am not getting why it is throwing exception in first code but not in second code attached below.我不明白为什么它在第一个代码中抛出异常,但在下面附加的第二个代码中却没有。 How to make it work without converting again to string and get dom object.如何在不再次转换为字符串的情况下使其工作并获得 dom object。

Exception in thread "main" java.lang.IllegalArgumentException: local part cannot be "null" when creating a QName
    at java.xml/javax.xml.namespace.QName.<init>(QName.java:185)
    at java.xml/javax.xml.namespace.QName.<init>(QName.java:129)
    at org.opensaml.xml.util.XMLHelper.constructQName(XMLHelper.java:433)
    at org.opensaml.xml.util.XMLHelper.getNodeQName(XMLHelper.java:171)
    at org.opensaml.xml.io.UnmarshallerFactory.getUnmarshaller(UnmarshallerFactory.java:81)
    at org.opensaml.xml.io.AbstractXMLObjectUnmarshaller.unmarshallChildElement(AbstractXMLObjectUnmarshaller.java:334)
    at org.opensaml.xml.io.AbstractXMLObjectUnmarshaller.unmarshall(AbstractXMLObjectUnmarshaller.java:127)
    at org.opensaml.xml.io.AbstractXMLObjectUnmarshaller.unmarshallChildElement(AbstractXMLObjectUnmarshaller.java:355)
    at org.opensaml.xml.io.AbstractXMLObjectUnmarshaller.unmarshall(AbstractXMLObjectUnmarshaller.java:127)
    at org.opensaml.ws.message.decoder.BaseMessageDecoder.unmarshallMessage(unmarshallMessage.java:208)
  1. For the below code it is throwing exception as explained above.对于下面的代码,它如上所述抛出异常。

     protected XMLObject unmarshallMessage(InputStream messageStream) throws MessageDecodingException { log.debug("Parsing message stream into DOM document"); try { Document messageDoc = parserPool.parse(messageStream); Element messageElem = messageDoc.getDocumentElement(); Element elementsByTagName = (Element) messageElem.getElementsByTagName("saml2:Assertion").item(0); Element issuer = messageDoc.createElement("saml2:Issuer"); issuer.setTextContent("emIDAM"); issuer.setAttribute("Format", "urn:oasis:names:tc:SAML:2.0:nameid-format:entity"); log.debug("Unmarshalling message DOM"); Unmarshaller unmarshaller = Configuration.getUnmarshallerFactory().getUnmarshaller(messageElem); if (unmarshaller == null) { log.debug("Unable to unmarshall message, no unmarshaller registered for message element " + XMLHelper.getNodeQName(messageElem)); throw new MessageDecodingException( "Unable to unmarshall message, no unmarshaller registered for message element " + XMLHelper.getNodeQName(messageElem)); } XMLObject message = unmarshaller.unmarshall(messageElem); return message; } catch (XMLParserException e) { log.error("Encountered error parsing message into its DOM representation", e); throw new MessageDecodingException("Encountered error parsing message into its DOM representation", e); } catch (UnmarshallingException e) { log.error("Encountered error unmarshalling message from its DOM representation", e); throw new MessageDecodingException("Encountered error unmarshalling message from its DOM representation", e); } catch (Exception e) { log.warn("Encountered error unmarshalling message from its DOM representation --->", e); throw new MessageDecodingException("Encountered error unmarshalling message from its DOM representation", e); } }
  2. But for the below code it is working fine, because here I have again converted to string and created the input stream and then get the dom which is passed for unmarshalling.但是对于下面的代码,它工作正常,因为在这里我再次转换为字符串并创建了输入 stream ,然后获取传递用于解组的 dom。

     protected XMLObject unmarshallMessage(InputStream messageStream) throws MessageDecodingException { log.debug("Parsing message stream into DOM document"); try { Document messageDoc = parserPool.parse(messageStream); Element messageElem = messageDoc.getDocumentElement(); Element elementsByTagName = (Element) messageElem.getElementsByTagName("saml2:Assertion").item(0); Element issuer = messageDoc.createElement("saml2:Issuer"); issuer.setTextContent("emIDAM"); issuer.setAttribute("Format", "urn:oasis:names:tc:SAML:2.0:nameid-format:entity"); //converting again to string and getting dom String xml = XMLHelper.nodeToString(messageElem); messageStream = new ByteArrayInputStream(xml.getBytes()); messageDoc = parserPool.parse(messageStream); messageElem = messageDoc.getDocumentElement(); log.debug("Unmarshalling message DOM"); Unmarshaller unmarshaller = Configuration.getUnmarshallerFactory().getUnmarshaller(messageElem); if (unmarshaller == null) { log.debug("Unable to unmarshall message, no unmarshaller registered for message element " + XMLHelper.getNodeQName(messageElem)); throw new MessageDecodingException( "Unable to unmarshall message, no unmarshaller registered for message element " + XMLHelper.getNodeQName(messageElem)); } XMLObject message = unmarshaller.unmarshall(messageElem); return message; } catch (XMLParserException e) { log.error("Encountered error parsing message into its DOM representation", e); throw new MessageDecodingException("Encountered error parsing message into its DOM representation", e); } catch (UnmarshallingException e) { log.error("Encountered error unmarshalling message from its DOM representation", e); throw new MessageDecodingException("Encountered error unmarshalling message from its DOM representation", e); } catch (Exception e) { log.warn("Encountered error unmarshalling message from its DOM representation --->", e); throw new MessageDecodingException("Encountered error unmarshalling message from its DOM representation", e); } }

Your problem may be related to your parser configuration, probably not configured as namespace aware.您的问题可能与您的解析器配置有关,可能未配置为命名空间感知。

Please, use something similar to the following code when initializing your parserPool :请在初始化parserPool时使用类似于以下代码的内容:

DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
DocumentBuilder parserPool = documentBuilderFactory.newDocumentBuilder();

My guess is that the second test runs successfully because under the hood XMLHelper nodeToString is using writeNode which in turn uses LSSerializer for performing the actual XML serialization.我的猜测是第二个测试成功运行,因为在XMLHelper nodeToString正在使用writeNode ,而LSSerializer来执行实际的 XML 序列化。 Since the parser is declared to be non-namespace aware, the resulting XML output and corresponding parsed Document will not contain namespace information or at least, it contains the information in such a way that the parsing process subsequently carried out by Unmarshaller deems it appropriate.由于解析器被声明为非命名空间感知,因此生成的 XML output 和相应的已解析Document将不包含命名空间信息,或者至少,它包含的信息以这样一种方式,即Unmarshaller随后执行的解析过程认为它是适当的。

In addition, please, be aware that the problem may be related with the way you are creating your new Element as well because you are not providing namespace information as well: when you use createElement , the resulting Element will not contain localName , prefix , or namespaceURI , all are set to null .此外,请注意,问题可能与您创建新Element的方式有关,因为您也没有提供命名空间信息:当您使用createElement时,生成的Element将不包含localNameprefixnamespaceURI ,全部设置为null Please, try the following code instead:请尝试以下代码:

Document messageDoc = parserPool.parse(messageStream);
Element messageElem = messageDoc.getDocumentElement();
Element assertionElem = (Element) messageElem.getElementsByTagName("saml2:Assertion").item(0);
Element issuerElement = messageDoc.createElementNS("urn:oasis:names:tc:SAML:2.0:assertion", "saml2:Issuer");
Attr formatAttr = messageDoc.createAttributeNS("urn:oasis:names:tc:SAML:2.0:assertion", "saml2:Format");
formatAttr.setNodeValue("urn:oasis:names:tc:SAML:2.0:nameid-format:entity");
issuerElement.setAttributeNode(formatAttr);
Text text = messageDoc.createTextNode("emIDAM");
issuerElement.appendChild(text);
assertionElem.appendChild(issuerElement);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM