From e70d96ea2e98dfcc843f8c3a226abead230c3b8b Mon Sep 17 00:00:00 2001 From: Marc Weise Date: Mon, 15 Dec 2025 09:35:46 +0100 Subject: [PATCH 1/3] Add jaxrs TLS server config --- .../dvalin/jaxrs/JAXRSServerConfig.java | 43 +++++++++++++++++-- .../main/resources/spring/jaxrs-server.xml | 6 +-- 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/jaxrs/src/main/java/de/taimos/dvalin/jaxrs/JAXRSServerConfig.java b/jaxrs/src/main/java/de/taimos/dvalin/jaxrs/JAXRSServerConfig.java index 306210cb..6a50b766 100644 --- a/jaxrs/src/main/java/de/taimos/dvalin/jaxrs/JAXRSServerConfig.java +++ b/jaxrs/src/main/java/de/taimos/dvalin/jaxrs/JAXRSServerConfig.java @@ -2,6 +2,7 @@ import de.taimos.dvalin.jaxrs.websocket.WebSocketContextHandler; import org.apache.cxf.Bus; +import org.apache.cxf.configuration.jsse.TLSServerParameters; import org.apache.cxf.jaxrs.JAXRSServerFactoryBean; import org.apache.cxf.transport.http_jetty.JettyHTTPServerEngine; import org.apache.cxf.transport.http_jetty.JettyHTTPServerEngineFactory; @@ -19,9 +20,18 @@ import org.springframework.context.annotation.ImportResource; import org.springframework.core.annotation.Order; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.TrustManagerFactory; +import java.io.File; import java.io.IOException; import java.lang.annotation.Annotation; +import java.nio.file.Files; import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; import java.util.List; /** @@ -43,6 +53,14 @@ public class JAXRSServerConfig { protected int port; @Value("${jaxrs.protocol:http}") protected String protocol; + + @Value("${jaxrs.server.keyStore:}") + protected String keyStorePath; + @Value("${jaxrs.server.keyStorePassword:}") + protected String keyStorePassword; + @Value("${jaxrs.server.keyStoreType:JKS}") + protected String keyStoreType; + @Value("${jetty.minThreads:5}") protected int minThreads; @Value("${jetty.maxThreads:150}") @@ -78,6 +96,9 @@ public JettyHTTPServerEngineFactory serverEngineFactory(Bus cxf, // } protected void createServerEngine(JettyHTTPServerEngineFactory factory, List handlers) throws GeneralSecurityException, IOException { + if (this.protocol.equals("https")) { + factory.setTLSServerParametersForPort(this.port, this.createTLSServerParameters()); + } JettyHTTPServerEngine engine = factory.createJettyHTTPServerEngine(this.host, this.port, this.protocol); engine.setThreadingParameters(this.createThreadingParameters()); engine.setSendServerVersion(this.sendVersion); @@ -92,6 +113,20 @@ protected ThreadingParameters createThreadingParameters() { return threadingParams; } + protected TLSServerParameters createTLSServerParameters() throws KeyStoreException, NoSuchAlgorithmException, IOException, CertificateException, UnrecoverableKeyException { + TLSServerParameters tlsParams = new TLSServerParameters(); + KeyStore keyStore = KeyStore.getInstance(this.keyStoreType); + keyStore.load(Files.newInputStream(new File(this.keyStorePath).toPath()), this.keyStorePassword.toCharArray()); + KeyManagerFactory keyFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + keyFactory.init(keyStore, this.keyStorePassword.toCharArray()); + tlsParams.setKeyManagers(keyFactory.getKeyManagers()); + + TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + trustFactory.init(keyStore); + tlsParams.setTrustManagers(trustFactory.getTrustManagers()); + return tlsParams; + } + protected ContextHandler createResourceContext(String contextPath, Resource base) { ContextHandler context = new ContextHandler(contextPath); ResourceHandler res = new ResourceHandler(); @@ -103,19 +138,19 @@ protected ContextHandler createResourceContext(String contextPath, Resource base @Order(1) @Bean(name = "web-server-context-static") public ContextHandler staticContextHandler() throws IOException { - return createResourceContext("/static", Resource.newResource("./static")); + return this.createResourceContext("/static", Resource.newResource("./static")); } @Order(2) @Bean(name = "web-server-context-web-fs") public ContextHandler webFSContextHandler() throws IOException { - return createResourceContext("/", Resource.newResource("./web")); + return this.createResourceContext("/", Resource.newResource("./web")); } @Order(3) @Bean(name = "web-server-context-web") public ContextHandler webContextHandler() { - return createResourceContext("/", Resource.newClassPathResource("/web")); + return this.createResourceContext("/", Resource.newClassPathResource("/web")); } @Order(10) @@ -129,4 +164,4 @@ public WebSocketContextHandler websocketContextHandler() { public DefaultHandler defaultHandler() { return new DefaultHandler(); } -} \ No newline at end of file +} diff --git a/jaxrs/src/main/resources/spring/jaxrs-server.xml b/jaxrs/src/main/resources/spring/jaxrs-server.xml index 0d83aed3..538ab163 100644 --- a/jaxrs/src/main/resources/spring/jaxrs-server.xml +++ b/jaxrs/src/main/resources/spring/jaxrs-server.xml @@ -21,11 +21,11 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxrs="http://cxf.apache.org/jaxrs" xsi:schemaLocation=" - http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd - http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd" + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd + http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd" profile="http"> - From 9ce3292da27e1d860e4969dabc0d56a756c51648 Mon Sep 17 00:00:00 2001 From: Marc Weise Date: Mon, 15 Dec 2025 13:44:52 +0100 Subject: [PATCH 2/3] Add jaxrs TLS server config to readme --- CHANGELOG.md | 1 + jaxrs/README.md | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5857b2c3..da358aa4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ * Bugfix: Better error handling in CloudconductorPropertyProvider * Fixed vulnerabilities: CVE-2024-13009(Jetty), CVE-2025-23184(Apache CXF), CVE-2024-57699 (Json-smart),CVE-2025-27533 (ActiveMQ) * Logging improvement and extension options for DaemonMessageListener +* Add TLS server parameters for JAX-RS # 1.37 * Major bug in interconnect core: DaemonScanner causes IllegalArgumentException due to wrong path of TimeoutException diff --git a/jaxrs/README.md b/jaxrs/README.md index 2d38895e..5dd8f5e4 100644 --- a/jaxrs/README.md +++ b/jaxrs/README.md @@ -64,6 +64,14 @@ password hashes secured by the SHA-512 function using a 512 bit salt and a dynam Several settings of the dvalin framework can be customized using system properties which are described in `de.taimos.dvalin.jaxrs.SpringCXFProperties`. +For HTTPS, configure protocol and KeyStore via system properties: +``` +jaxrs.protocol=https +jaxrs.server.keyStore=/path/to/keystore.jks +jaxrs.server.keyStorePassword=password +jaxrs.server.keyStoreType=JKS +``` + ### Testing moved to `test` sub-project. From 35aeb0e23ad6a14422a84ded424591dfe4d79d88 Mon Sep 17 00:00:00 2001 From: Marc Weise Date: Mon, 15 Dec 2025 16:07:53 +0100 Subject: [PATCH 3/3] Adjust jaxrs server url --- .../java/de/taimos/dvalin/jaxrs/swagger/OpenAPIProvider.java | 2 +- .../java/de/taimos/dvalin/jaxrs/context/JAXRSContextImpl.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jaxrs-swagger/src/main/java/de/taimos/dvalin/jaxrs/swagger/OpenAPIProvider.java b/jaxrs-swagger/src/main/java/de/taimos/dvalin/jaxrs/swagger/OpenAPIProvider.java index 11724c1a..ec4cf9a7 100644 --- a/jaxrs-swagger/src/main/java/de/taimos/dvalin/jaxrs/swagger/OpenAPIProvider.java +++ b/jaxrs-swagger/src/main/java/de/taimos/dvalin/jaxrs/swagger/OpenAPIProvider.java @@ -66,7 +66,7 @@ protected boolean hasAnnotation(Class clz, Class ann) { protected void configureServerURL(OpenAPI openAPI) { String port = System.getProperty(SpringCXFProperties.JAXRS_BINDPORT, System.getProperty("svc.port", "8080")); - String serverUrl = System.getProperty(SpringCXFProperties.SERVER_URL, "http://localhost:" + port); + String serverUrl = System.getProperty(SpringCXFProperties.SERVER_URL, System.getProperty("jaxrs.protocol", "http") + "://localhost:" + port); String path = System.getProperty(SpringCXFProperties.JAXRS_PATH, ""); if (!path.startsWith("/")) { serverUrl += "/"; diff --git a/jaxrs/src/main/java/de/taimos/dvalin/jaxrs/context/JAXRSContextImpl.java b/jaxrs/src/main/java/de/taimos/dvalin/jaxrs/context/JAXRSContextImpl.java index cd608984..d68ed898 100644 --- a/jaxrs/src/main/java/de/taimos/dvalin/jaxrs/context/JAXRSContextImpl.java +++ b/jaxrs/src/main/java/de/taimos/dvalin/jaxrs/context/JAXRSContextImpl.java @@ -47,7 +47,7 @@ @Component public class JAXRSContextImpl implements DvalinRSContext { - @Value("${server.url:http://localhost:${jaxrs.bindport:${svc.port:8080}}}") + @Value("${server.url:${jaxrs.protocol:http}://localhost:${jaxrs.bindport:${svc.port:8080}}}") private String serverURL; @Override