我正在尝试使用现有的断言元素为令牌更新过程创建一个带有OpenSAML的SAML 2.0断言。
// 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
}
我得到两个错误。
- 当使用
DefaultBootstrap.bootstrap();
时,它抛出一个例外java.lang.UnsupportedOperationException: This parser does not support specification "null" version "null"
- 当
DefaultBootstrap.bootstrap()
被移除时,它抛出断言samlAssertion =(Assertion) unmarshaller.unmarshall(x1);
我错过了什么吗?
首先,您必须始终运行引导程序,否则会出现错误。
看起来第一个错误是因为您使用了太旧的JAXP实现https://lists.internet2.edu/sympa/arc/mace-opensaml-users/2010-01/msg00015.html
OpenSAML团队建议使用Apache Xerces或Xalan。
有两个错误导致了异常。当然,为了继续编组或解组,必须完成bootsrap()
。
-
在前一行代码中,
DOM
实现更改为DOOM
。DocumentBuilderFactoryImpl.setDOOMRequired(true);
尽管它已被弃用,但代码仍在使用它。所以在bootstrap()
之前,它必须设置为false
,因为底层JAXB实现使用DOM。 -
同样,将
OMElement assertionOMElement
转换为Element
也会抛出这个异常。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.
解决方案是将OMElement
转换为String
,然后从中构建Document
并获得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();