Java Opensaml解组器提供Opensaml本地部分的消息不能为;空";创建QName异常时
我正在使用Spring SAML,从IDP响应我接收issuer作为属性ID,因此我希望在Spring SAML中接收后更改响应,因此我已重写了方法unmarshall,该方法将解析消息并为此更改xml元素。在执行此操作时,如果我在解析后直接使用元素来解组,则它会工作,但如果我执行dom操作,则会出现以下异常。我不明白为什么它在第一个代码中抛出异常,但在下面附加的第二个代码中却没有。如何使其工作而无需再次转换为字符串并获取dom对象Java Opensaml解组器提供Opensaml本地部分的消息不能为;空";创建QName异常时,java,spring-saml,opensaml,Java,Spring Saml,Opensaml,我正在使用Spring SAML,从IDP响应我接收issuer作为属性ID,因此我希望在Spring SAML中接收后更改响应,因此我已重写了方法unmarshall,该方法将解析消息并为此更改xml元素。在执行此操作时,如果我在解析后直接使用元素来解组,则它会工作,但如果我执行dom操作,则会出现以下异常。我不明白为什么它在第一个代码中抛出异常,但在下面附加的第二个代码中却没有。如何使其工作而无需再次转换为字符串并获取dom对象 Exception in thread "main&
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");
//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
正在使用,而后者反过来使用LSSerializer
执行实际的XML序列化。由于解析器被声明为非名称空间感知,因此产生的XML输出和相应的解析的文档
将不包含名称空间信息,或者至少,它包含的信息的方式使解组器随后执行的解析过程认为是适当的
此外,请注意,问题可能与您创建新元素的方式有关,因为您没有提供名称空间信息:当您使用createElement
时,生成的元素将不包含localName
,前缀
,或者namespaceURI
,都设置为null
。请改为尝试以下代码:
documentmessagedoc=parserPool.parse(messageStream);
Element messageElem=messageDoc.getDocumentElement();
元素assertionElem=(元素)messageElem.getElementsByTagName(“saml2:Assertion”).item(0);
Element-issuerElement=messageDoc.createElements(“urn:oasis:names:tc:SAML:2.0:assertion”,“saml2:Issuer”);
Attr formatAttr=messageDoc.createAttributeNS(“urn:oasis:names:tc:SAML:2.0:assertion”,“saml2:Format”);
setNodeValue(“urn:oasis:names:tc:SAML:2.0:nameid格式:entity”);
setAttributeNode(formatAttr);
Text Text=messageDoc.createTextNode(“emIDAM”);
issuerElement.appendChild(文本);
assertionElem.appendChild(issuerElement);
@ashok您是否能够测试建议的方法?
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);
}
}