我不知道如何将错误记录到Shibboleth项目中,因此我将编写一些我在OpenSAML签名验证中遇到的结果。有一个问题与OpenSAML(2.0)尝试验证SAML元数据(EntitiesDescriptor)中的签名的方式有关。
我试图用FilesystemMetadataProvider拼命验证我的SAML元数据结构中的签名,但是它总是抛出NullPointerException。在其他地方还有其他一些关于这个问题的文章,但似乎没有人知道它的确切原因。
现在我第一次尝试的是这样的:
FilesystemMetadataProvider provider = new FilesystemMetadataProvider(new File("metadata.xml"));
provider.setRequireValidMetadata(true);
provider.setParserPool(new BasicParserPool());
provider.initialize();
EntitiesDescriptor ed = provider.getEntitiesDescriptor("My Servers");
SignatureValidator validator = new SignatureValidator(getTrustedCredential());
validator.validate(ed.getSignature());
这常常会导致异常:
org.opensaml.xml.signature.SignatureValidator.validate(SignatureValidator.java:69)中的java.lang.NullPointerException
在对XMLTooling和OpenSAML类进行一些调试之后,我发现了错误的原因。问题似乎在于org.opensaml.xml.signature.impl.SignatureImpl类中处理XMLSignature的方式:
public void releaseDOM() {
super.releaseDOM();
**this.xmlSignature = null;**
if (this.keyInfo != null) {
this.keyInfo.releaseChildrenDOM(true);
this.keyInfo.releaseDOM();
}
}
public XMLSignature getXMLSignature() {
return this.xmlSignature;
}
public void setXMLSignature(XMLSignature signature) {
this.xmlSignature = ((XMLSignature)prepareForAssignment(this.xmlSignature, signature));
}
现在,SignatureValidator按顺序运行这些方法setXMLSignature() - > releaseDOM() - > getXMLSignature()无法验证EntitiesDescriptor。但是,对于其他签名类型,这似乎没问题。
作为一种解决方法,有两种方法可以验证签名:
1)对SignatureImpl类进行逆向工程并删除" this.xmlSignature = null;"来自releaseDOM()方法
2)使用XML解析和解组重新实现签名验证(如下所示)
File file = new File("metadata.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.parse(file);
UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory();
Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(document.getDocumentElement());
EntitiesDescriptor ed = (EntitiesDescriptor) unmarshaller.unmarshall(document.getDocumentElement());
SignatureValidator validator = new SignatureValidator(getTrustedCredential());
validator.validate(ed.getSignature());
还有其他人看过这个问题吗?
答案 0 :(得分:0)
如何提交bug等:https://shibboleth.net/community/
您不需要对其进行反向工程,OpenSAML源代码可用:http://svn.shibboleth.net/view/java-opensaml2/trunk/src
OpenSAML源代码库具有覆盖其大部分代码库的单元测试。您可以在这里学习如何使用该库。例如,元数据的签名验证封装在SignatureValidationFilter类中。这是一个单元测试,向您展示如何使用它:http://svn.shibboleth.net/view/java-opensaml2/trunk/src/test/java/org/opensaml/saml2/metadata/provider/SignatureValidationFilterTest.java
通过此单元测试,您可以看到他们使用SAMLSignatureProfileValidator作为Validator的实现。它比普通的SignatureValidator更复杂。
尝试SignatureValidationFilter。如果它仍然无效,请在此处发布您的元数据。