2013-10-27 3 views
32

Ich versuche, Spring Security für die Arbeit mit der eingebetteten Tomcat-Instanz von Spring Boot einzurichten. Es gibt einige grundlegende Beispiele, die das tun, aber ich bleibe hängen, wo sie aufhören - sie tun grundlegende Authentifizierung über HTTP (nicht HTTPS).Wie kann ich meine .keystore-Datei mit Spring Boot und Tomcat angeben?

Ich könnte wahrscheinlich es funktionieren, wenn ich Zugriff auf die Tomcat-Konfigurationsdateien hätte (server.xml) aber da Spring Boot eine eingebettete Tomcat-Instanz verwendet (was ansonsten eine große Bequemlichkeit ist), habe ich keinen Zugriff auf die Tomcat-Konfigurationsdateien (zumindest, nicht meines Wissens).

Möglicherweise gibt es eine application.properties Einstellung für diese, aber ich konnte es nicht aufspüren. Ich habe Verweise auf ein server.contextPath Feld in application.properties gesehen, dass ich vermute, dass etwas mit Tomcat Konfigurationsdateien zu tun haben kann. Selbst wenn es damit zusammenhängt, würde ich sowieso nicht wissen, wo ich anfangen soll - alle Tomcat SSL-Anweisungen, die ich gesehen habe, beginnen mit der Bearbeitung einer bestehenden server.xml-Datei, die nicht von Grund auf neu erstellt wird.

Kann dies mit Spring Boot gemacht werden (entweder indem man irgendwie ein Snippet von server.xml oder durch andere Mittel spezifiziert)? Wenn nicht, was wäre der einfachste Weg, dies zu tun? Ich verstehe, dass ich die Tomcat-Komponente von Spring Boot ausschließen muss, aber ich würde es lieber vermeiden, wenn möglich.

+1

Ich habe ein anderes Beispiel gefunden, die eine andere 'application.properties' Einstellung verwendet,' server.tomcat.basedir', die mich schlägt als eher mit der eingebetteten Tomcat-Konfiguration zu tun haben. Ich kann es auch nicht tun, aber es ist wahrscheinlich näher an der richtigen Richtung und kann meine Frage klarer machen. – Dave

+1

Kein Glück mit den Umgebungsvariablen der Befehlszeile: '-Djavax.net.ssl.keyStore =/Pfad/zu/keystore' '-Djavax.net.ssl.keyStorePassword = keyStorePass' entweder. – Dave

Antwort

17

Es stellt sich heraus, dass es einen Weg gibt, dies zu tun, obwohl ich nicht sicher bin, dass ich den "richtigen" Weg gefunden habe, da dies Stunden des Lesens von Quellcode aus mehreren Projekten erforderte. Mit anderen Worten, das könnte eine Menge dummer Arbeit sein (aber es funktioniert).

Erstens gibt es keine Möglichkeit, die eingebettete Tomcat-Datei server.xml abzurufen oder zu ersetzen. Dies muss programmgesteuert erfolgen.

Zweitens hilft die Einstellung 'require_https' nicht, da Sie auf diese Weise keine Cert-Informationen festlegen können. Es tut einrichten Weiterleitung von http zu https, aber es gibt Ihnen keine Möglichkeit, https Arbeit so die Weiterleitung ist nicht hilfreich. Verwenden Sie es jedoch mit dem Zeug, macht https arbeiten.

Um zu beginnen, müssen Sie eine EmbeddedServletContainerFactory wie in der Embedded Servlet Container Support docs erläutert bereitstellen. Die Dokumente sind für Java, aber das Groovy würde ziemlich gleich aussehen. Beachten Sie, dass ich die in ihrem Beispiel verwendete @Value Annotation nicht erkennen konnte, sie wird aber nicht benötigt. Für groovy, fügen Sie diese einfach in eine neue .groovy Datei ein und fügen Sie diese Datei in die Befehlszeile ein, wenn Sie spring booten.

Jetzt sagen die Anweisungen, dass Sie die TomcatEmbeddedServletContainerFactory Klasse, die Sie in diesem Code erstellt haben, anpassen können, so dass Sie web.xml Verhalten ändern können, und das ist wahr, aber für unsere Zwecke ist es wichtig zu wissen, dass Sie auch verwenden können es, um server.xml Verhalten zu schneidern. Wenn Sie die Quelle für die Klasse lesen und sie mit den eingebetteten Tomcat-Dokumenten vergleichen, sehen Sie, dass dies der einzige Ort ist, an dem Sie das tun können. Die interessante Funktion ist TomcatEmbeddedServletContainerFactory.addConnectorCustomizers(), die nicht viel von den Javadocs aussehen mag, aber tatsächlich gibt Ihnen das eingebettete Tomcat-Objekt, um sich anzupassen. Übergeben Sie einfach Ihre eigene Implementierung von TomcatConnectorCustomizer und stellen Sie die gewünschten Dinge auf die gegebene Connector in der void customize(Connector con) Funktion. Nun, es gibt ungefähr eine Milliarde Dinge, die Sie mit der Connector tun können und ich konnte keine brauchbaren Dokumente dafür finden, aber die createConnector() Funktion in dieser this guys personal Spring-embedded-Tomcat project ist eine sehr praktische Anleitung.Meine Implementierung sah so aus:

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; 
} 
} 

Der Autowiring wird diese Implementierung einen Lauf mit ihm abholen. Sobald ich meine kaputte Keystore-Datei repariert habe (stelle sicher, dass du keytool mit -storetype pkcs12, nicht -storepass pkcs12 an anderer Stelle anrufst), funktionierte das. Außerdem wäre es viel besser, die Parameter (Port, Passwort, etc) als Konfigurationseinstellungen für das Testen und so weiterzugeben. Ich bin mir sicher, dass es möglich ist, wenn Sie die @Value Annotation mit Groovy arbeiten können.

+2

Vielen Dank, dass Sie sich mit dem https-Support im Spring-Boot beschäftigt haben. Vielleicht ist dies eine Einschränkung des Spring Boot, die einen Fehlerbericht erfordert? HTTPS ist eine ziemlich grundlegende Voraussetzung für jede Webanwendung, es ist seltsam, dass es nicht besser dokumentiert und besser unterstützt wird. – Jay

+2

Dies ist jetzt in der Spring-Boot-Dokumentation dokumentiert: https://github.com/spring-projects/spring-boot/blob/master/docs/howto.md – Jay

+0

Was ist der Unterschied zwischen dem Geben dieser SSL-Eigenschaften über application.yml und haben wir eine eigene Implementierung von TomcatConnectorCustomizer? – yathirigan

0

Wenn Sie Ihre connector customizer nicht implementieren möchten, können Sie die Bibliothek erstellen und importieren (https://github.com/ycavatars/spring-boot-https-kit), die vordefinierte connector customizer bereitstellt. Laut README müssen Sie nur Ihren Keystore erstellen, connector.https.* konfigurieren, die Bibliothek importieren und @ComponentScan("org.ycavatars.sboot.kit") hinzufügen. Dann haben Sie eine HTTPS-Verbindung.

41

Beginnend mit Frühlings-Boot-1.2 können Sie mithilfe von SSL application.properties oder application.yml konfigurieren. Hier ist ein Beispiel für application.properties:

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

Die gleiche Sache mit application.yml:

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

Hier ist ein Link auf die current reference documentation.

+3

Es funktioniert in der Tat. Spring Boot ist großartig! – Maksim

+2

Was ist der Unterschied zwischen der Angabe dieser SSL-Eigenschaften über application.yml und unserer eigenen Implementierung von TomcatConnectorCustomizer (wie in der folgenden Antwort)? – yathirigan

+4

Einfachheit vs Kontrolle. –

2

Für externe Schlüsselspeicher, Präfix mit „file:“

server.ssl.key-store=file:config/keystore 
Verwandte Themen