繁体   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 . 这样做时,如果我在解析解组后直接使用 Element,它正在工作,但如果我进行 dom 操作,则会给出以下异常。 我不明白为什么它在第一个代码中抛出异常,但在下面附加的第二个代码中却没有。 如何在不再次转换为字符串的情况下使其工作并获得 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. 对于下面的代码,它如上所述抛出异常。

     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. 但是对于下面的代码,它工作正常,因为在这里我再次转换为字符串并创建了输入 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); } }

您的问题可能与您的解析器配置有关,可能未配置为命名空间感知。

请在初始化parserPool时使用类似于以下代码的内容:

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

我的猜测是第二个测试成功运行,因为在XMLHelper nodeToString正在使用writeNode ,而LSSerializer来执行实际的 XML 序列化。 由于解析器被声明为非命名空间感知,因此生成的 XML output 和相应的已解析Document将不包含命名空间信息,或者至少,它包含的信息以这样一种方式,即Unmarshaller随后执行的解析过程认为它是适当的。

此外,请注意,问题可能与您创建新Element的方式有关,因为您也没有提供命名空间信息:当您使用createElement时,生成的Element将不包含localNameprefixnamespaceURI ,全部设置为null 请尝试以下代码:

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