如何解决创建 QName 异常时,Opensaml unmarshallMessage 给出 opensaml 本地部分不能为“null”
我正在使用 Spring SAML,从 IDP 响应我接收颁发者作为属性 ID,所以我想在 spring saml 接收后更改响应,所以我重写了 unmarshall 方法,该方法将解析消息并为此目的更改 xml 元素。在执行此操作时,如果我在解析后直接使用 Element 来解组它正在工作,但是如果我进行 dom 操作,则会给出以下异常。我不明白为什么它在第一个代码中抛出异常,但在下面附加的第二个代码中没有。如何在不再次转换为字符串并获取 dom 对象的情况下使其工作。
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)
-
对于下面的代码,它抛出异常,如上所述。
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); } }
-
但是对于下面的代码,它工作正常,因为在这里我再次转换为字符串并创建了输入流,然后获取了用于解组的 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,e); } }
解决方法
你的问题可能与你的解析器配置有关,可能没有配置为命名空间感知。
请在初始化您的 parserPool
时使用类似于以下代码的内容:
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
DocumentBuilder parserPool = documentBuilderFactory.newDocumentBuilder();
我的猜测是第二个测试成功运行,因为在幕后 XMLHelper
nodeToString
正在使用 writeNode
,而 https://help.poralix.com/articles/mysql-access-denied-you-need-the-super-privilege-for-this-operation 又使用 LSSerializer
来执行实际的 XML 序列化。由于解析器被声明为非命名空间感知的,因此生成的 XML 输出和相应的解析 Document
将不包含命名空间信息,或者至少,它包含的信息使得解析过程随后由 { {1}} 认为合适。
此外,请注意该问题也可能与您创建新 Unmarshaller
的方式有关,因为您没有提供命名空间信息:当您使用 Element
时,生成的 createElement
将不包含 Element
、localName
或 prefix
,所有这些都设置为 namespaceURI
。请改为尝试以下代码:
null
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。