web-dev-qa-db-fra.com

les entrées de certificat approuvées ne sont pas protégées par mot de passe Spring SAML

J'ai généré le fichier testIdp.cer en copiant l'entrée 509 de l'IDP que je prévois de connecter. J'ai ensuite créé un fichier JKS en exécutant la commande suivante

keytool -importcert -alias adfssigning -keystore C:\Users\user\Desktop\samlKeystore.jks -file    C:\Users\user\Desktop\testIdp.cer

Une fois exécuté, il a demandé d'entrer un mot de passe pour lequel j'ai donné un mot de passe. Pour la question "Faire confiance à ce certificat? [Non]:", j'ai donné "y" en entrée. Le message est sorti comme "Le certificat a été ajouté au magasin de clés".

Ensuite, j'ai configuré les détails suivants dans securityContext.xml

<bean id="keyManager" class="org.springframework.security.saml.key.JKSKeyManager">
    <constructor-arg value="classpath:security/samlKeystore.jks"/>
    <constructor-arg type="Java.lang.String" value="mypassword"/>
    <constructor-arg>
        <map>
            <entry key="adfssigning" value="mypassword"/>
        </map>
    </constructor-arg>
    <constructor-arg type="Java.lang.String" value="adfssigning"/>
</bean>

<bean class="org.springframework.security.saml.metadata.ExtendedMetadata">
  <property name="alias" value="adfssigning" />
  <property name="signingKey" value="adfssigning"/>     
</bean>

Mais lorsque j'exécute l'application, j'obtiens les deux exceptions suivantes lorsque le serveur démarre et lorsque je charge la page d'accueil de l'application. Quelqu'un peut-il me faire savoir si je manque quelque chose d'autre?.

Cette exception se produit lorsque je démarre le serveur

Caused by: org.opensaml.saml2.metadata.provider.FilterException: Signature trust establishment failed for metadata entry
at org.opensaml.saml2.metadata.provider.SignatureValidationFilter.verifySignature(SignatureValidationFilter.Java:327)
at org.opensaml.saml2.metadata.provider.SignatureValidationFilter.processEntityGroup(SignatureValidationFilter.Java:240)
at org.opensaml.saml2.metadata.provider.SignatureValidationFilter.doFilter(SignatureValidationFilter.Java:158)
at org.opensaml.saml2.metadata.provider.AbstractMetadataProvider.filterMetadata(AbstractMetadataProvider.Java:493)
at org.opensaml.saml2.metadata.provider.AbstractReloadingMetadataProvider.processNonExpiredMetadata(AbstractReloadingMetadataProvider.Java:395)

Cette exception se produit lorsque j'exécute la page d'accueil de mon application

Java.lang.UnsupportedOperationException: trusted certificate entries are not password-protected
at Java.security.KeyStoreSpi.engineGetEntry(Unknown Source)
at Java.security.KeyStore.getEntry(Unknown Source)
at org.opensaml.xml.security.credential.KeyStoreCredentialResolver.resolveFromSource(KeyStoreCredentialResolver.Java:132)
17
SM KUMAR

Votre .cer le certificat ne contient qu'une clé publique, vous ne devez pas définir <entry key="adfssigning" value="mypassword"/> pour les clés publiques; il ne peut être utilisé que pour des particuliers. Retirez simplement l'entrée adfssigning et assurez-vous d'inclure une clé privée à la place - comme dans l'exemple d'application Spring SAML.

Le magasin de clés SAML peut contenir deux types de clés de base - les clés publiques et privées (plus leurs certificats). Chaque clé a un alias qui est utilisé pour s'y référer. Le magasin de clés lui-même peut être protégé par un mot de passe (fourni dans le deuxième paramètre constructeur), plus chaque clé privée peut également être protégée par un mot de passe supplémentaire (ceux-ci sont définis dans le troisième paramètre du constructeur dans une carte d'alias-> mot de passe). Les clés publiques que vous importez dans le magasin de clés (comme vous l'avez fait avec la commande ci-dessus) ne doivent pas être définies dans cette carte. Ils seront automatiquement disponibles après avoir été importés sans déclarations supplémentaires. Pour que Spring SAML fonctionne, le magasin de clés doit contenir au moins une clé privée (l'exemple d'application contient une clé privée avec l'alias apollo) et son alias doit être fourni dans le troisième paramètre du constructeur.

Votre exemple ci-dessus échoue, car vous avez importé une clé publique, mais l'avez incluse dans la carte qui ne peut être utilisée que pour des clés privées.

10

Vladimir a répondu correctement à la question pourquoi l'erreur se produit. Dans ma réponse, je veux montrer comment vous pouvez importer un certificat dans le magasin de clés pour résoudre ce problème:

Vous devez importer le certificat et la clé privée qui ne peut pas être effectuée directement par keytool.

La solution décrite détaillée se trouve ici: https://stackoverflow.com/a/8224863/1909531

Voici un extrait:

openssl pkcs12 -export -in server.crt -inkey server.key \
           -out server.p12 -name [some-alias] \
           -CAfile ca.crt -caname root

keytool -importkeystore \
    -deststorepass [changeit] -destkeypass [changeit] -destkeystore server.keystore \
    -srckeystore server.p12 -srcstoretype PKCS12 -srcstorepass some-password \
    -alias [some-alias]
9
Matthias M

Cette erreur se produit également lorsque vous n'avez pas de clé privée dans votre magasin de clés. SAML utilise la clé privée pour générer les métadonnées du fournisseur de services utilisées pour communiquer avec l'IDP. Ajoutez-en un au magasin de clés comme ceci: keytool -genkey -v -keystore some_key_store.jks -alias some_alias -keyalg RSA -keysize 2048 -validity 36500 Remplissez les questions et définissez la validité sur un nombre de jours approprié. (Dans mon exemple, il est valable 100 ans) N'oubliez pas d'ajouter le certificat public d'IDP. Ensuite, vous devriez être prêt à partir.

2

Pour ceux qui recherchent des réponses dans la configuration Java config, veuillez commenter la ligne passwords.put ("mykeyalias", "mystorepass"); .... indiquée dans l'extrait de code ci-dessous.

@Bean
public KeyManager keyManager() {
    DefaultResourceLoader loader = new DefaultResourceLoader();
    Resource storeFile = loader.getResource("classpath:saml-keystore.jks");
    Map<String, String> passwords = new HashMap<>();
    // passwords.put("mykeyalias", "mystorepass");
    return new JKSKeyManager(storeFile, "mystorepass", passwords, "mykeyalias");
}
0
Sandeep Shukla

Obtenez le certificat public en utilisant la commande openssl:

openssl s_client -showcerts -connect iam-sso.google.net:443 </dev/null 2>/dev/null|openssl x509 -outform PEM >mycertfile.pem

Importez-le dans le Keystore:

keytool -import -alias "new-qet-alias" -keystore /usr/share/Tomcat8/webapps/ROOT/WEB-INF/classes/saml/samlKeystore.jks -file mycertfile.pem
0
Velu