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>
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With