web-dev-qa-db-fra.com

Comment puis-je spécifier mon fichier .keystore avec Spring Boot et Tomcat?

J'essaie de configurer Spring Security pour qu'il fonctionne avec l'instance Tomcat intégrée de Spring Boot. Quelques exemples basiques le font, mais je suis bloqué là où ils s’arrêtent: ils effectuent une authentification de base sur HTTP (pas HTTPS).

Je pourrais probablement le faire fonctionner si j'avais accès aux fichiers de configuration Tomcat (server.xml), Mais Spring Boot utilise une instance intégrée de Tomcat (ce qui est très pratique), je n'ai pas accès aux fichiers de configuration de Tomcat. (Du moins pas à ma connaissance).

Il peut y avoir un paramètre application.properties Pour cela, mais je n'ai pas été en mesure de le localiser. J'ai déjà vu des références à un champ server.contextPath Dans application.properties, Ce qui pourrait avoir quelque chose à voir avec le remplacement des fichiers de configuration Tomcat. Même s'il est lié, je ne saurais pas par où commencer - toutes les instructions SSL de Tomcat que j'ai vues commencent par l'édition d'un fichier server.xml Existant, et non par la construction de celle-ci.

Cela peut-il être fait avec Spring Boot (en spécifiant en quelque sorte un extrait de code server.xml Ou par un autre moyen)? Si non, quel serait le moyen le plus simple de le faire? Je comprends que je devrais peut-être exclure le composant Tomcat de Spring Boot, mais je préférerais éviter cela si possible.

42
Dave

Il s’avère qu’il ya un moyen de le faire, bien que je ne sois pas sûr d’avoir trouvé le "bon" chemin, car cela a nécessité des heures de lecture du code source de plusieurs projets. En d'autres termes, cela pourrait être beaucoup de travail stupide (mais cela fonctionne).

Premièrement, il n’ya aucun moyen d’obtenir le fichier server.xml dans le Tomcat intégré, que ce soit pour l’augmenter ou le remplacer. Cela doit être fait par programme.

Deuxièmement, le paramètre "require_https" n'aide pas, car vous ne pouvez pas définir les informations de certification de cette façon. Il configure le transfert de http à https, mais il ne vous permet pas de faire fonctionner le protocole https et le transfert n'est donc pas utile. Cependant, utilisez-le avec les éléments ci-dessous, qui fait faire fonctionner https.

Pour commencer, vous devez fournir un EmbeddedServletContainerFactory comme expliqué dans les Documents de support du conteneur de servlets incorporés . Les docs sont pour Java mais le Groovy aurait à peu près la même apparence. Notez que je n'ai pas réussi à le faire reconnaître l'annotation @Value Utilisée dans leur exemple, mais Pour groovy, placez-le simplement dans un nouveau fichier .groovy et incluez-le sur la ligne de commande lorsque vous lancez springboot.

Maintenant, les instructions disent que vous pouvez personnaliser la classe TomcatEmbeddedServletContainerFactory que vous avez créée dans ce code afin de pouvoir modifier le comportement de web.xml, ce qui est vrai, mais pour nos besoins, il est important de savoir que vous pouvez également utilisez-le pour adapter le comportement server.xml. En effet, en lisant le source de la classe et en le comparant à la documentation Embedded Tomcat, vous voyez que c’est le seul endroit pour le faire. La fonction intéressante est TomcatEmbeddedServletContainerFactory.addConnectorCustomizers(), ce qui ne ressemble peut-être pas beaucoup aux Javadocs, mais vous donne en réalité l'objet Embedded Tomcat à personnaliser. Passez simplement votre propre implémentation de TomcatConnectorCustomizer et définissez ce que vous voulez sur le Connector donné dans la fonction void customize(Connector con). Maintenant, il y a environ un milliard de choses que vous pouvez faire avec Connector et je ne pouvais pas trouver de documentation utile pour cela, mais la fonction createConnector() dans ce ce gars personnel intégré à Spring -Tomcat project est un guide très pratique. Ma mise en œuvre a fini par ressembler à ceci:

package com.deepdownstudios.server

import org.springframework.boot.context.embedded.Tomcat.TomcatConnectorCustomizer
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory
import org.springframework.boot.context.embedded.Tomcat.TomcatEmbeddedServletContainerFactory
import org.Apache.catalina.connector.Connector;
import org.Apache.coyote.http11.Http11NioProtocol;
import org.springframework.boot.*
import org.springframework.stereotype.*

@Configuration
class MyConfiguration {

@Bean
public EmbeddedServletContainerFactory servletContainer() {
final int port = 8443;
final String keystoreFile = "/path/to/keystore"
final String keystorePass = "keystore-password"
final String keystoreType = "pkcs12"
final String keystoreProvider = "SunJSSE"
final String keystoreAlias = "Tomcat"

TomcatEmbeddedServletContainerFactory factory = 
        new TomcatEmbeddedServletContainerFactory(this.port);
factory.addConnectorCustomizers( new TomcatConnectorCustomizer() {
    void    customize(Connector con) {
        Http11NioProtocol proto = (Http11NioProtocol) con.getProtocolHandler();
            proto.setSSLEnabled(true);
        con.setScheme("https");
        con.setSecure(true);
        proto.setKeystoreFile(keystoreFile);
        proto.setKeystorePass(keystorePass);
        proto.setKeystoreType(keystoreType);
        proto.setProperty("keystoreProvider", keystoreProvider);
        proto.setKeyAlias(keystoreAlias);
    }
});
return factory;
}
}

Le câblage automatique prendra en charge cette implémentation. Une fois que j'ai corrigé mon fichier de clés altéré (assurez-vous d'appeler keytool avec -storetype pkcs12, Pas -storepass pkcs12 Comme indiqué ailleurs), cela a fonctionné. En outre, il serait bien préférable de fournir les paramètres (port, mot de passe, etc.) sous forme de paramètres de configuration pour les tests et autres ... Je suis sûr que c'est possible si vous pouvez obtenir l'annotation @Value fonctionner avec Groovy.

18
Dave

À partir de Spring Boot 1.2, vous pouvez configurer SSL à l’aide de application.properties ou application.yml. Voici un exemple pour application.properties:

server.port = 8443
server.ssl.key-store = classpath:keystore.jks
server.ssl.key-store-password = secret
server.ssl.key-password = another-secret

Même chose avec application.yml:

server:
  port: 8443
  ssl:
    key-store: classpath:keystore.jks
    key-store-password: secret
    key-password: another-secret

Voici un lien vers le documentation de référence actuelle .

57
Willie Wheeler

Pour les magasins de clés externes, préfixe avec "fichier:"

server.ssl.key-store=file:config/keystore 
11
pma

Si vous ne voulez pas implémenter votre connector customizer, Vous pouvez construire et importer la bibliothèque ( https://github.com/ycavatars/spring-boot-https-kit ) qui fournit prédéfini connector customizer. Selon le fichier README, il vous suffit de créer votre magasin de clés, de configurer connector.https.*, D'importer la bibliothèque et d'ajouter @ComponentScan("org.ycavatars.sboot.kit"). Ensuite, vous aurez une connexion HTTPS.

0
guest