OpenSAML(2.0)EntitiesDescriptor签名验证无效

时间:2015-01-23 14:18:21

标签: java validation opensaml

我不知道如何将错误记录到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());

还有其他人看过这个问题吗?

1 个答案:

答案 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。如果它仍然无效,请在此处发布您的元数据。