From 6d6b8e68ab7a6be2c700ee09e095d0396e413ceb Mon Sep 17 00:00:00 2001 From: Emmanuel Bruno <emmanuel.bruno@univ-tln.fr> Date: Tue, 9 Mar 2021 14:54:05 +0100 Subject: [PATCH] cleans up and documents. --- .gitignore | 4 +- pom.xml | 65 +++++++++++++++++++ .../samples/jaxrs/client/BiblioClient.java | 4 +- .../samples/jaxrs/server/BiblioServer.java | 45 ++++++++++++- 4 files changed, 114 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 466716b..1198f78 100644 --- a/.gitignore +++ b/.gitignore @@ -33,4 +33,6 @@ proguard/ # Package Files # *.jar *.war -*.ear \ No newline at end of file +*.ear + +src/main/resources/ssl/* diff --git a/pom.xml b/pom.xml index edaf75b..b1d5a96 100644 --- a/pom.xml +++ b/pom.xml @@ -68,6 +68,19 @@ <artifactId>jersey-client</artifactId> </dependency> + <!-- HTTP2 --> + <dependency> + <groupId>org.glassfish.grizzly</groupId> + <artifactId>grizzly-http2</artifactId> + <version>3.0.0</version> + </dependency> + + <dependency> + <groupId>org.glassfish.grizzly</groupId> + <artifactId>grizzly-npn-bootstrap</artifactId> + <version>2.0.0</version> + </dependency> + <!-- Eclipse Collections --> <dependency> <groupId>org.eclipse.collections</groupId> @@ -405,6 +418,58 @@ </executions> </plugin> + <!-- SSL Certificates --> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>keytool-maven-plugin</artifactId> + <version>1.5</version> + <executions> + <execution> + <phase>generate-resources</phase> + <id>generateKeyPair</id> + <goals> + <goal>generateKeyPair</goal> + </goals> + <configuration> + <skipIfExist>true</skipIfExist> + </configuration> + </execution> + <execution> + <phase>generate-resources</phase> + <id>generateCertificateRequest</id> + <goals> + <goal>generateCertificateRequest</goal> + </goals> + <configuration> + <file>src/main/resources/ssl/test.csr</file> + </configuration> + </execution> + <execution> + <phase>generate-resources</phase> + <id>generateCertificate</id> + <goals> + <goal>generateCertificate</goal> + </goals> + <configuration> + <infile>src/main/resources/ssl/test.csr</infile> + <outfile>src/main/resources/ssl/test.crt</outfile> + <rfc>true</rfc> + </configuration> + </execution> + </executions> + <configuration> + <keystore>src/main/resources/ssl/cert.jks</keystore> + <storepass>storepass</storepass> + <keypass>storepass</keypass> + <alias>localhost</alias> + <validity>100</validity> + <sigalg>SHA256withRSA</sigalg> + <keyalg>RSA</keyalg> + <!--dname>cn=com.example</dname--> + <dname>cn=localhost.localdomain</dname> + </configuration> + </plugin> + </plugins> </build> <properties> diff --git a/src/main/java/fr/univtln/bruno/samples/jaxrs/client/BiblioClient.java b/src/main/java/fr/univtln/bruno/samples/jaxrs/client/BiblioClient.java index 6bdaf72..2af92d4 100644 --- a/src/main/java/fr/univtln/bruno/samples/jaxrs/client/BiblioClient.java +++ b/src/main/java/fr/univtln/bruno/samples/jaxrs/client/BiblioClient.java @@ -37,11 +37,11 @@ public class BiblioClient { //Log in to get the token with basci authentication String email = "john.doe@nowhere.com"; - String password = "admin"; + String passwd = "admin"; String token = webResource.path("biblio/login") .request() .accept(MediaType.TEXT_PLAIN) - .header("Authorization", "Basic " + java.util.Base64.getEncoder().encodeToString((email + ":" + password).getBytes())) + .header("Authorization", "Basic " + java.util.Base64.getEncoder().encodeToString((email + ":" + passwd).getBytes())) .get(String.class); if (!token.isBlank()) { log.info("token received."); diff --git a/src/main/java/fr/univtln/bruno/samples/jaxrs/server/BiblioServer.java b/src/main/java/fr/univtln/bruno/samples/jaxrs/server/BiblioServer.java index 5255f79..a4f1bd1 100644 --- a/src/main/java/fr/univtln/bruno/samples/jaxrs/server/BiblioServer.java +++ b/src/main/java/fr/univtln/bruno/samples/jaxrs/server/BiblioServer.java @@ -2,10 +2,16 @@ package fr.univtln.bruno.samples.jaxrs.server; import lombok.extern.java.Log; import org.glassfish.grizzly.http.server.HttpServer; +import org.glassfish.grizzly.http.server.NetworkListener; +import org.glassfish.grizzly.http2.Http2AddOn; +import org.glassfish.grizzly.http2.Http2Configuration; +import org.glassfish.grizzly.ssl.SSLContextConfigurator; +import org.glassfish.grizzly.ssl.SSLEngineConfigurator; import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory; import org.glassfish.jersey.logging.LoggingFeature; import org.glassfish.jersey.server.ResourceConfig; +import java.io.IOException; import java.net.URI; import java.util.logging.Level; import java.util.logging.Logger; @@ -18,15 +24,19 @@ public class BiblioServer { // Base URI the Grizzly HTTP server will listen on public static final String BASE_URI = "http://0.0.0.0:9998/myapp"; + public static final int TLS_PORT = 4443; + /** * Main method. * * @param args the input arguments */ - public static void main(String[] args) throws InterruptedException { + public static void main(String[] args) throws InterruptedException, IOException { log.info("Rest server starting..." + BASE_URI); final HttpServer server = startServer(); + addTLSandHTTP2(server); + //The server will be shutdown at the end of the program Runtime.getRuntime().addShutdownHook(new Thread(server::shutdownNow)); @@ -57,4 +67,37 @@ public class BiblioServer { // exposing the Jersey application at BASE_URI return GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc); } + + /** + * Adds a https (TLS) listener to secure connexion and adds http2 on this protocol. + * @param httpServer + * @return + * @throws IOException + */ + public static HttpServer addTLSandHTTP2(HttpServer httpServer) throws IOException { + NetworkListener listener = + new NetworkListener("TLS", + NetworkListener.DEFAULT_NETWORK_HOST, + TLS_PORT); + listener.setSecure(true); + + // We add the certificate stored in a java keystore in src/main/resources/ssl + // By default a self signed certificate is generated by maven (see pom.xml) + SSLContextConfigurator sslContextConfigurator = new SSLContextConfigurator(); + sslContextConfigurator.setKeyStoreBytes(BiblioServer.class.getResourceAsStream("/ssl/cert.jks").readAllBytes()); + sslContextConfigurator.setKeyStorePass("storepass"); + + listener.setSSLEngineConfig(new SSLEngineConfigurator(sslContextConfigurator, false, false, false)); + + // Create default HTTP/2 configuration and provide it to the AddOn + Http2Configuration configuration = Http2Configuration.builder().build(); + Http2AddOn http2Addon = new Http2AddOn(configuration); + + // Register the Addon. + listener.registerAddOn(http2Addon); + httpServer.addListener(listener); + + return httpServer; + } + } -- GitLab