Hi,
ich stehe vor folgender Herausforderung:
Ich habe eine Anwendung die über Jetty im Web bereitgestellt wird. Eine spezifische URL dieser Anwendung soll nun mit einem Client-Zertifikat geschützt werden.
Beispiel:
Beim Aufruf von https://www.example.com ist kein Client-Zertifikat erforderlich.
Beim Aufruf von https://www.example.com/api/ ist ein Client-Zertifikat erforderlich.
Die start.ini von Jetty sieht so aus:
Die Anwendung wird per xml-Datei in Jetty eingebunden:
Es gibt eine Java-Datei die per Servlet die API-URL bereitstellt. Hier der Kopf:
Damit die JVM das Client-Zertifikat aus dem Request ausliest muss meines Wissens entweder setNeedClientAuth() oder setWantClientAuth() auf true gesetzt werden (oder beides).
Meine Frage:
Wie verbinde ich SslContextFactory.Server mit dem HttpServletRequest? Ohne eine Verbindung wird diese Konfiguration doch völlig ignoriert.
Ich suche leider schon sehr lange nach einer Lösung. Vlt. hat einer von euch einen Hinweis?
Danke schonmal im Voraus
ich stehe vor folgender Herausforderung:
Ich habe eine Anwendung die über Jetty im Web bereitgestellt wird. Eine spezifische URL dieser Anwendung soll nun mit einem Client-Zertifikat geschützt werden.
Beispiel:
Beim Aufruf von https://www.example.com ist kein Client-Zertifikat erforderlich.
Beim Aufruf von https://www.example.com/api/ ist ein Client-Zertifikat erforderlich.
Die start.ini von Jetty sieht so aus:
Code:
--module=server
jetty.httpConfig.sendServerVersion=false
--module=jsp
--module=annotations
--module=deploy
--module=logging-jetty
--module=console-capture
--module=ext
--module=requestlog
--module=http-forwarded
--module=plus
--module=rewrite
--module=jstl
--module=servlets
--module=http
--module=ssl
--module=https
jetty.sslContext.keyStorePath=credentials/server.keystore
jetty.sslContext.keyStorePassword=mypassword
jetty.sslContext.keyManagerPassword=mypassword
jetty.sslContext.trustStorePath=credentials/server.keystore
jetty.sslContext.trustStorePassword=mypassword
jetty.sslContext.needClientAuth=true
Die Anwendung wird per xml-Datei in Jetty eingebunden:
XML:
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="war">/path/to/app.war</Set>
<Set name="contextPath">/</Set>
<Set name="extractWAR">false</Set>
<Set name="copyWebDir">false</Set>
<Set name="copyWebInf">true</Set>
<Set name="persistTempDirectory">false</Set>
</Configure>
Es gibt eine Java-Datei die per Servlet die API-URL bereitstellt. Hier der Kopf:
Java:
@WebServlet(
name = "api",
urlPatterns = {"spapi"},
loadOnStartup = 1
)
public class api extends HttpServlet {
// Logging-Objekt
private MyLogging logging = null;
/**
* Initialisierung des Servlet-Containers beim Starten von diesem.
* Hier werden für die Funktionalität der API wichtige Vorbereitungen getroffen.
*
* @param config die ServletConfig-Konfiguration
*/
public void init(ServletConfig config) {
// Lade das Logging als Objekt ein.
logging = vioLogging.getInstance();
}
/**
* Verarbeitung von GET-Requests an den Endpunkt.
*
* @param request der Request als HttpServletRequest-Objekt
* @param response die Antwort als HttpServletResponse-Objekt
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
extractCertificate(request,response);
}
/**
* Verarbeitung von POST-Requests an den Endpunkt.
*
* @param request der Request als HttpServletRequest-Objekt
* @param response die Antwort als HttpServletResponse-Objekt
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) {
}
/**
* Verarbeitung von PUT-Requests an den Endpunkt.
*
* @param request der Request als Objekt
* @param response die Antwort als Objekt
*/
protected void doPut(HttpServletRequest request, HttpServletResponse response) {
}
protected X509Certificate extractCertificate(HttpServletRequest req, HttpServletResponse res) {
SslContextFactory.Server sslFactory = new SslContextFactory.Server();
sslFactory.setNeedClientAuth(true);
sslFactory.setWantClientAuth(true);
logging.write("api", "clientcert: " + req.getHeader("ssl_client_cert"));
logging.write("api", "authtype: " + req.getAuthType());
boolean authResult = false;
try{
authResult = req.authenticate(res);
}
catch (Exception e){
logging.write("api auth Exception", e.getMessage());
}
logging.write("api auth result", "result: " + authResult);
X509Certificate[] certs = (X509Certificate[]) req.getAttribute("javax.servlet.request.X509Certificate");
logging.write("api", "certs: " + certs);
if (null != certs && certs.length > 0) {
return certs[0];
}
throw new RuntimeException("No X.509 client certificate found in request");
}
}
Damit die JVM das Client-Zertifikat aus dem Request ausliest muss meines Wissens entweder setNeedClientAuth() oder setWantClientAuth() auf true gesetzt werden (oder beides).
Meine Frage:
Wie verbinde ich SslContextFactory.Server mit dem HttpServletRequest? Ohne eine Verbindung wird diese Konfiguration doch völlig ignoriert.
Ich suche leider schon sehr lange nach einer Lösung. Vlt. hat einer von euch einen Hinweis?
Danke schonmal im Voraus