Dieses Dokument beschreibt die Konfiguration des HTTPWriter für HTTPS mit Client Zertifizierung
.
Keystores
In der Java Welt werden Zertifikate in sogenannten Keystores verwaltet. Um Zertifikate im- oder exportieren gibt es das Kommandozeilen basierte keytool (%JAVA_HOME%\bin). Außerdem gibt es den keyman von IBM
, ein grafisches Tool. Download
. Die Pfade in der km.bat müssen angepasst werden, anschließend kann das Programm über diese gestartet werden.
Mit dem Tool ist es relativ einfach möglich neue Keystores zu erstellen und Zertifikate unterschiedlicher Formate (.crt, .p12, ...) zu importieren. Beim Speichern des Keystores sollte immer ein Passwort angegeben werden. Bei manchen Tests kam es zu Problemen, wenn das Passwort des Keystores frei gelassen wurde.
SSL Verbindung aufbauen
Um eine einfache SSL Verbindung mit dem HTTPWriter herzustellen, genügt es in der URL "https" statt "http" zuverwenden. Sofern das Server Zertifikat von einer vertrauenswürdigen Zertifizierungsstelle ausgestellt ist, wird die sichere Verbindung automatisch aufgebaut. Die JVM kann die Zertifikate automatisch validieren, so ähnlich wie der Webbrowser.
Server Zertifizierung
Oftmals kommt es vor, dass die Server Zertifikate aus Kostengründen nicht von einer offiziellen Zertifizierungsstelle ausgestellt sind. Der Webbrowser bringt in diesem Fall eine Warnung, dass das Zertifikat ungültig ist und weigert sich zunächst die Seite anzuzeigen. Der HTTPWriter reagiert in diesem Fall mit einer Exception:
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Im Webbrowser kann man nun das (ungültige) Zertifikat herunterladen und installieren, um die Seite trotz Warnung anzuzeigen. So ähnlich funktioniert auch der HTTPWriter. Das Server Zertifikat muss per keytool oder keyman in einen Keystore importiert werden. Dann muss dem HTTPWriter per System Propertys mitgeteilt werden, wo der Keystore zu finden ist. Die Propertys sind JVM weit gültig, es ist darauf zu achten, dass es nicht zu Seiteneffekten kommt.
Die Server Zertifikate müssen über folgende Propertys bekannt gemacht werden, bevor der HTTPWriter ausgeführt wird.
System.setProperty("javax.net.ssl.trustStore", "C:\\trust.store"); System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
Ist das gültige Server Zertifikat nicht vorhanden, kann es mit Hilfe eines Webbrowsers vom Server heruntergeladen und exportiert werden. Dazu muss die entsprechende Website aufgerufen werden. Wenn die Fehlermeldung des Browsers erscheint, "Webseite vertrauen" oder ähnliches klicken. Im Firefox kann das Zertifikat nun über Extras > Einstellungen > Verschlüsselung > Zertifikate anzeigen > Server exportiert werden. Für weitere Funktionen gibt es das Firefox Plugin Cert Viewer Plus
.
Client Zertifizierung
Manche Server erwarten ein Zertifikat vom Client, um diesen zu identifizieren. Wird ein ungültiges oder gar kein Zertifikat vom Client übermittelt, antwortet der Server mit dem HTTP Status Code 403.7.
Das Client Zertifikat wird vom HTTPWriter ebenfalls automatisch an den Server geschickt sobald dieser es anfordert. Wie das Server Zertifikat auch muss es allerdings zunächst in einen Keystore importiert werden.
Die Client Zertifikate müssen über folgende Propertys bekannt gemacht werden, bevor der HTTPWriter ausgeführt wird.
System.setProperty("javax.net.ssl.keyStore", "C:\\key.store"); System.setProperty("javax.net.ssl.keyStorePassword", "changeit");
Das Client Zertifikat muss vom Betreiber des Webservers zur Verfügung gestellt werden.
System Property setzen
Alternativ zu den Codebeispielen, können die Propertys auch über den SystemPropertyService konfiguriert werden. Dazu können Sie entweder den Dienst über den "Dienste"-Dialog im Backend erstellen und dort im Eigenschaften-Tab die gewünschten Einstellungen eintragen, oder den Service direkt in der services.xml eintragen.
<service name="SystemPropertyService" class="com.busintel.logging.SystemPropertyService"> <property name="javax.net.ssl.keyStore" value="/home/xyz/key.store"/> <property name="javax.net.ssl.keyStorePassword" value="changeit"/> </service>
Troubleshooting
Fehler:
com.busintel.fuel.api.protocol.MessageWriterException: Executing request failed.
at com.busintel.fuel.writer.HTTPWriter.flush(HTTPWriter.java:244)
...
Caused by: java.net.SocketException: Default SSL context init failed: null
at javax.net.ssl.DefaultSSLSocketFactory.createSocket(SSLSocketFactory.java:176)
...
Fehlerursache: Pfade zu den Keystores sind falsch. Evtl. auch falls keine Rechte zum Lesen der Dateien.
Fehler:
Caused by: com.busintel.fuel.api.protocol.MessageWriterException: Executing request failed.
at com.busintel.fuel.writer.HTTPWriter.flush(HTTPWriter.java:244)
at com.busintel.fuel.internalapi.ChainSteps.WriterStep.actualTransformation(WriterStep.java:282)
... 6 more
Caused by: java.net.ConnectException: Connection timed out
at java.net.PlainSocketImpl.socketConnect(Native Method)
...
Fehlerursache: Server nicht erreichbar; URL falsch; Port von Firewall gesperrt