3
votes

I'm integrating the spring-saml2-sample app into my own application. My Service Provider connects to a Shibboleth IDP. I'm testing the SP with the private certificate provided in samlKeystore.jks that came with the Spring Security SAML application. I registered the IDP signing public key in the keystore by using the command: keytool -importcert -alias idpSignKey -keypass passwordS -file key.cer -keystore samlKeystore.jks

I'm able to run the app and login with the IDP. I can see in the log that the public certificate they send me back in the saml message corresponds to the one I have in the idp metadata and registered in the keystore. My app breaks while getting the idp credential from the JKSKeyManager.

java.lang.UnsupportedOperationException: trusted certificate entries are not password-protected java.security.KeyStoreSpi.engineGetEntry(Unknown Source) java.security.KeyStore.getEntry(Unknown Source) org.opensaml.xml.security.credential.KeyStoreCredentialResolver.resolveFromSource(KeyStoreCredentialResolver.java:132) org.opensaml.xml.security.credential.AbstractCriteriaFilteringCredentialResolver.resolve(AbstractCriteriaFilteringCredentialResolver.java:57) org.opensaml.xml.security.credential.AbstractCredentialResolver.resolveSingle(AbstractCredentialResolver.java:30) org.opensaml.xml.security.credential.AbstractCredentialResolver.resolveSingle(AbstractCredentialResolver.java:26) org.springframework.security.saml.key.JKSKeyManager.resolveSingle(JKSKeyManager.java:172) org.springframework.security.saml.key.JKSKeyManager.getCredential(JKSKeyManager.java:194) org.springframework.security.saml.trust.MetadataCredentialResolver.retrieveFromMetadata(MetadataCredentialResolver.java:102) org.opensaml.security.MetadataCredentialResolver.resolveFromSource(MetadataCredentialResolver.java:169)

This is how the KeyManager looks in contextSecurity.xml:

<!-- Central storage of cryptographic keys --> <bean id="keyManager" class="org.springframework.security.saml.key.JKSKeyManager"> <constructor-arg value="classpath:security/samlKeystore.jks"/> <constructor-arg type="java.lang.String" value="nalle123"/> <constructor-arg> <map> <entry key="apollo" value="nalle123"/> <entry key="idpSignKey" value="passwordS"/> <entry key="idpEncKey" value="passwordE"/> </map> </constructor-arg> <constructor-arg type="java.lang.String" value="apollo"/> </bean>

This is the extended metadata for the idp:

<bean class="org.springframework.security.saml.metadata.ExtendedMetadata"> <property name="local" value="false"/> <property name="securityProfile" value="metaiop"/> <property name="sslSecurityProfile" value="pkix"/> <property name="signingKey" value="idpSignKey"/> <property name="encryptionKey" value="idpEncKey"/> <property name="requireArtifactResolveSigned" value="false"/> <property name="requireLogoutRequestSigned" value="false"/> <property name="requireLogoutResponseSigned" value="false"/> <property name="idpDiscoveryEnabled" value="false"/> </bean>

1

1 Answers

5
votes

Certificates for IDPs do not need to be typically imported to the keystore as they are provided from the IDP's metadata. You should only use ExtendedMetadata and the properties signingKey and/or encryptionKey in case you want to supplement keys already available in the metadata.

As the file key.cer contains only public key of your IDP, you cannot password protect it. You should simply remove it from the Map used for initialization of the JKSKeyManager as it only needs passwords for entries which include private keys. The initialization would then look like this:

<!-- Central storage of cryptographic keys -->
<bean id="keyManager" class="org.springframework.security.saml.key.JKSKeyManager">
    <constructor-arg value="classpath:security/samlKeystore.jks"/>
    <constructor-arg type="java.lang.String" value="nalle123"/>
    <constructor-arg>
        <map>
            <entry key="apollo" value="nalle123"/>
        </map>
    </constructor-arg>
    <constructor-arg type="java.lang.String" value="apollo"/>
</bean>