Я понятия не имею, как зарегистрировать ошибку в проекте Shibboleth, поэтому я напишу некоторые выводы, с которыми я столкнулся при проверке подписи OpenSAML. Существует проблема, связанная с тем, как OpenSAML (2.0) пытается проверять подписи в метаданных SAML (EntitiesDescriptor).
Я отчаянно пытался проверить подпись в своей структуре метаданных SAML с помощью FilesystemMetadataProvider, однако он всегда выдает мне исключение 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());
Это постоянно приводит к возникновению исключения:
java.lang.NullPointerException в org.opensaml.xml.signature.SignatureValidator.validate(SignatureValidator.java:69)
После некоторой отладки классов XMLTooling и OpenSAML я нашел причину ошибки. Проблема, похоже, заключается в том, как обрабатывается XMLSignature в классе org.opensaml.xml.signature.impl.SignatureImpl:
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());
Кто-нибудь еще видел эту проблему?