У меня возникла проблема с интеграцией Spring SAML для создания правильного файла метаданных для моего IdP. Мне были выданы новые SSL-сертификаты SHA256. Я выполнил все шаги, чтобы создать соответствующее хранилище ключей и настроить файл конфигурации безопасности Spring. Я буквально прошел 98% пути, но в сгенерированном файле метаданных отсутствует одна вещь, которую я не могу понять, почему она не устанавливается.
Вот моя конфигурация ExtendedMetadata для MetadataGeneratorFilter:
<bean id="metadataGeneratorFilter" class="org.springframework.security.saml.metadata.MetadataGeneratorFilter">
<constructor-arg>
<bean class="org.springframework.security.saml.metadata.MetadataGenerator">
<property name="entityId" value="urn:myentityidhere"/>
<property name="entityBaseURL" value="https://${saml.url}"/>
<property name="extendedMetadata">
<bean class="org.springframework.security.saml.metadata.ExtendedMetadata">
<property name="signMetadata" value="true"/>
<property name="signingAlgorithm" value="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<property name="alias" value="ceo"/>
<property name="signingKey" value="${saml.sp.alias}"/>
<property name="encryptionKey" value="${saml.sp.alias}"/>
</bean>
</property>
</bean>
</constructor-arg>
When I run my app and go to the /saml/metadata URI to get Spring to generate the metadata file I need to send to my IdP, the SHA256 algo gets correctly set on the SignatureMethod, but the child DigestMethod tag's algorithm value is still set to SHA1, when I need that ALSO set to SHA256 along with the DigestValue to be a SHA256 value and not a SHA1 value.
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<ds:Reference URI="#urn_myentityidhere">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>xxxxxxx</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
Может ли кто-нибудь подсказать мне, как/что мне нужно установить, чтобы значение алгоритма DigestMethod также было установлено на 256? Я полагал, что поскольку это дочерний элемент тега SignedInfo, он унаследует значение signingAlgorithm из конфигурации расширенных метаданных, но, увы, это не так.
Любая помощь будет принята с благодарностью. Огромное спасибо.
РЕШЕНИЕ – Если кому-то интересно
Итак, после дня копания я решил просто реализовать это сам. Я расширил класс ExtendedMetadata, добавив поле дайджестMethodAlgorithm и соответствующие геттеры/сеттеры:
/**
* Algorithm used for creation of digest method of this entity. At the moment only used for metadata signatures.
* Only valid for local entities.
*/
private String digestMethodAlgorithm;
/**
* Returns digest method algorithm value
* @return String
*/
public String getDigestMethodAlgorithm()
{
return digestMethodAlgorithm;
}
/**
* Sets the digest method algorithm to use when signing the SAML messages.
* This can be used, for example, when a strong algorithm is required (e.g. SHA 256 instead of SHA 128).
* If this property is null, then the {@link org.opensaml.xml.Configuration} default algorithm will be used instead.
*
* Value only applies to local entities.
*
* At the moment the value is only used for signatures on metadata.
*
* Typical values are:
* http://www.w3.org/2001/04/xmlenc#sha1
* http://www.w3.org/2001/04/xmlenc#sha256
* http://www.w3.org/2001/04/xmlenc#sha384
* http://www.w3.org/2001/04/xmlenc#sha512
* http://www.w3.org/2001/04/xmlenc#ripemd160
*
* @param digestMethodAlgorithm The new digest method algorithm to use
* @see org.opensaml.xml.signature.SignatureConstants
*/
public void setDigestMethodAlgorithm(String digestMethodAlgorithm)
{
this.digestMethodAlgorithm = digestMethodAlgorithm;
}
Затем я изменил свою конфигурацию безопасности spring сверху, чтобы включить это новое свойство bean-компонента, которое будет установлено в моей конфигурации MetadataGenerator:
<bean id="metadataGeneratorFilter" class="org.springframework.security.saml.metadata.MetadataGeneratorFilter">
<constructor-arg>
<bean class="org.springframework.security.saml.metadata.MetadataGenerator">
<property name="entityId" value="urn:myentityidhere"/>
<property name="entityBaseURL" value="https://${saml.url}"/>
<property name="extendedMetadata">
<bean class="org.springframework.security.saml.metadata.ExtendedMetadata">
<property name="signMetadata" value="true"/>
<property name="signingAlgorithm" value="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<property name="digestMethodAlgorithm" value="http://www.w3.org/2001/04/xmlenc#sha256"/>
<property name="alias" value="ceo"/>
<property name="signingKey" value="${saml.sp.alias}"/>
<property name="encryptionKey" value="${saml.sp.alias}"/>
</bean>
</property>
</bean>
</constructor-arg>
Then I also had to make two changes to the SAMLUtil class. In getmetadataAsString, in the isSignMetadata() if-clause, I pulled out the injected value for the digestMethodAlgorithm set by the config above and then further modified the marshallAndSignMessage method to accept a new input parameter which I further use to get the DigestMethod algo set properly.
Внутри SAMLUtil.getMetaDataAsString, строка 572
...
String digestMethodAlgorithm = extendedMetadata.getDigestMethodAlgorithm();
element = SAMLUtil.marshallAndSignMessage(descriptor, credential, signingAlgorithm, digestMethodAlgorithm, keyGenerator);
...
Внутри SAMLUtil.marshallAndSignMessage, сразу после строки 437, я добавил/изменил следующее:
...
BasicSecurityConfiguration secConfig = null;
if (digestMethodAlgorithm != null)
{
secConfig = (BasicSecurityConfiguration) Configuration.getGlobalSecurityConfiguration();
secConfig.setSignatureReferenceDigestMethod(digestMethodAlgorithm);
}
try {
SecurityHelper.prepareSignatureParams(signature, signingCredential, secConfig, keyInfoGenerator);
} catch (org.opensaml.xml.security.SecurityException e) {
throw new MessageEncodingException("Error preparing signature for signing", e);
}
...
Я перекомпилировал весь базовый пакет Spring SAML через Gradle, spring-security-saml-1.0.0.RELEASE, скопировал новый jar-файл из каталога build/libs в свой проект, развернул веб-приложение, указал браузер на /saml/metadata и успешно получил файл метаданных с правильной частью файла метаданных, подписанной SHA256.
Я собираюсь посмотреть, что я могу сделать, чтобы зафиксировать это в репозитории git для этого проекта, потому что я не хочу терять эту возможность, поскольку проект делает будущие выпуски. Никогда раньше не участвовал в подобных проектах с открытым исходным кодом.
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<ds:Reference URI="#urn_myentityidhere">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>xxxxxx</ds:DigestValue>
</ds:Reference>