我在获取 Spring SAML 集成以为我的 IdP 生成正确的元数据文件时遇到问题。我获得了新的 SHA256 SSL 证书。我已经完成了所有步骤来创建适当的 keyStore 并设置了我的 Spring 安全配置文件。从字面上看,我已经完成了 98% 的工作,但是生成的元数据文件中缺少一件事,我终其一生都无法弄清楚为什么它没有被设置。
这是 MetadataGeneratorFilter 的 ExtendedMetadata 配置:
<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>
当我运行我的应用程序并转到 /saml/metadata URI 以让 Spring 生成我需要发送到我的 IdP 的元数据文件时,SHA256 算法在 SignatureMethod 上得到正确设置,但子 DigestMethod 标记的算法值仍然设置到 SHA1,当我需要将 ALSO 设置为 SHA256 以及 DigestValue 为 SHA256 值而不是 SHA1 值时。
<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 标记的子项,它会从 Extendedmetadata 配置继承 signingAlgorithm 值,但可惜不是。
任何帮助将不胜感激。非常感谢。
解决方案 - 如果有人关心
所以,经过一天的挖掘,我决定自己实现这个。我通过添加字段 digestMethodAlgorithm 扩展了 ExtendedMetadata 类,并添加了适当的 getter/setter:
/**
* 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>
然后我还必须对 SAMLUtil 类进行两次更改。在 getmetadataAsString 中,在 isSignMetadata() if 子句中,我提取了上面配置设置的 digestMethodAlgorithm 的注入值,然后进一步修改了 marshallAndSignMessage 方法以接受一个新的输入参数,我进一步使用它来正确设置 DigestMethod 算法.
在 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);
}
...
我通过 Gradle 重新编译了整个 Spring SAML 核心包 spring-security-saml-1.0.0.RELEASE,将新 jar 从 build/libs 目录复制到我的项目,部署了 webapp,将我的浏览器指向 /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>