Skip to content

Commit

Permalink
Update vanilla Akka gRPC to not use TLS in examples
Browse files Browse the repository at this point in the history
  • Loading branch information
chbatey committed Aug 15, 2018
1 parent 087b55a commit 9eec9cf
Show file tree
Hide file tree
Showing 16 changed files with 25 additions and 369 deletions.
2 changes: 1 addition & 1 deletion docs/src/main/paradox/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ This library is in preview mode: basic functionality is in place, but API's and
build system plugins are still expected to be improved.

The API on both sides (Client and Server) is a simple Akka Streams-based one.
We plan to also provide a 'power user' API for each of these ([#191](https://github.com/akka/akka-grpc/issues/191), [#179](https://github.com/akka/akka-grpc/issues/179)).
The client has a 'power user' API and the planned for the server in [#179](https://github.com/akka/akka-grpc/issues/179)).

The client side is
currently implemented on top of [io.grpc:grpc-netty-shaded](https://mvnrepository.com/artifact/io.grpc/grpc-netty-shaded),
Expand Down
8 changes: 5 additions & 3 deletions docs/src/main/paradox/server/walkthrough.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,11 @@ In the example this was done from the `main` method, but you could also do this
@@@
HTTP/2 can only be served over TLS. That means that you need to configure your server with TLS information to provide certificates.
The example code contains a snippet about how to set up the TLS context from certificates and keys provided from resources on the
classpath. In a real application, you would probably want to load the keys from outside the application jar instead.
The above example does not use TLS and is configured to only serve HTTP/2.
To allow HTTP and HTTP/2 and gRPC on the same port TLS must be used.
That means that you need to configure your server with TLS information to provide certificates.
TODO Document how to configure TLS ([#191](https://github.com/akka/akka-grpc/issues/352)
## Serving multiple services
Expand Down
50 changes: 2 additions & 48 deletions plugin-tester-java/src/main/java/example/myapp/CombinedServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@
package example.myapp;

import akka.actor.ActorSystem;
import akka.http.javadsl.ConnectWithHttps;
import akka.http.javadsl.ConnectionContext;
import akka.http.javadsl.HttpsConnectionContext;
import akka.http.javadsl.*;
import akka.stream.ActorMaterializer;
import akka.stream.Materializer;
import com.typesafe.config.Config;
Expand All @@ -33,7 +31,6 @@

//#import
import akka.grpc.javadsl.ServiceHandler;
import akka.http.javadsl.Http;
import akka.http.javadsl.model.HttpRequest;
import akka.http.javadsl.model.HttpResponse;
import akka.japi.Function;
Expand Down Expand Up @@ -63,54 +60,11 @@ public static void main(String[] args) throws Exception {

Http.get(sys).bindAndHandleAsync(
serviceHandlers,
ConnectWithHttps.toHostHttps("127.0.0.1", 8080).withCustomHttpsContext(serverHttpContext()),
ConnectHttp.toHost("127.0.0.1", 8080, UseHttp2.always()),
mat)
//#concatOrNotFound
.thenAccept(binding -> {
System.out.println("gRPC server bound to: " + binding.localAddress());
});
}

private static HttpsConnectionContext serverHttpContext() throws Exception {
// FIXME how would end users do this? TestUtils.loadCert? issue #89
String keyEncoded = read(CombinedServer.class.getResourceAsStream("/certs/server1.key"))
.replace("-----BEGIN PRIVATE KEY-----\n", "")
.replace("-----END PRIVATE KEY-----\n", "")
.replace("\n", "");

byte[] decodedKey = Base64.getDecoder().decode(keyEncoded);

PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(decodedKey);

KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey privateKey = kf.generatePrivate(spec);

CertificateFactory fact = CertificateFactory.getInstance("X.509");
Certificate cer = fact.generateCertificate(CombinedServer.class.getResourceAsStream("/certs/server1.pem"));

KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(null);
ks.setKeyEntry("private", privateKey, new char[0], new Certificate[]{cer});

KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
keyManagerFactory.init(ks, null);

SSLContext context = SSLContext.getInstance("TLS");
context.init(keyManagerFactory.getKeyManagers(), null, new SecureRandom());

return ConnectionContext.https(context);
}

private static String read(InputStream in) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream(Math.max(64, in.available()));
byte[] buffer = new byte[32 * 1024];
int bytesRead = in.read(buffer);
while (bytesRead >= 0) {
baos.write(buffer, 0, bytesRead);
bytesRead = in.read(buffer);
}

byte[] bytes = baos.toByteArray();
return new String(bytes, "UTF-8");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,12 @@
package example.myapp.helloworld;

import akka.actor.ActorSystem;
import akka.http.javadsl.ConnectWithHttps;
import akka.http.javadsl.ConnectionContext;
import akka.http.javadsl.Http;
import akka.http.javadsl.HttpsConnectionContext;
import akka.http.javadsl.*;
import akka.stream.ActorMaterializer;
import akka.stream.Materializer;
import com.typesafe.config.Config;
import com.typesafe.config.ConfigFactory;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.FileInputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;

import example.myapp.helloworld.grpc.*;

class GreeterServer {
Expand All @@ -50,63 +30,13 @@ public static void main(String[] args) throws Exception {
// Bind implementation to localhost:8080
Http.get(sys).bindAndHandleAsync(
GreeterServiceHandlerFactory.create(impl, mat),
// HTTP/2 servers are required to use TLS
ConnectWithHttps.toHostHttps("127.0.0.1", 8080)
// provide TLS certificate and keys
.withCustomHttpsContext(serverHttpContext()),
ConnectHttp.toHost("127.0.0.1", 8080, UseHttp2.always()),
mat)
.thenAccept(binding -> {
System.out.println("gRPC server bound to: " + binding.localAddress());
});

// ActorSystem threads will keep the app alive until `system.terminate()` is called
}

/**
* Read certificate and keys from resources on the classpath. In a real application you
* would probably want to provide those from outside.
*/
private static HttpsConnectionContext serverHttpContext() throws Exception {
// FIXME how would end users do this? TestUtils.loadCert? issue #89
String keyEncoded = read(GreeterServer.class.getResourceAsStream("/certs/server1.key"))
.replace("-----BEGIN PRIVATE KEY-----\n", "")
.replace("-----END PRIVATE KEY-----\n", "")
.replace("\n", "");

byte[] decodedKey = Base64.getDecoder().decode(keyEncoded);

PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(decodedKey);

KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey privateKey = kf.generatePrivate(spec);

CertificateFactory fact = CertificateFactory.getInstance("X.509");
Certificate cer = fact.generateCertificate(GreeterServer.class.getResourceAsStream("/certs/server1.pem"));

KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(null);
ks.setKeyEntry("private", privateKey, new char[0], new Certificate[]{cer});

KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
keyManagerFactory.init(ks, null);

SSLContext context = SSLContext.getInstance("TLS");
context.init(keyManagerFactory.getKeyManagers(), null, new SecureRandom());

return ConnectionContext.https(context);
}

private static String read(InputStream in) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream(Math.max(64, in.available()));
byte[] buffer = new byte[32 * 1024];
int bytesRead = in.read(buffer);
while (bytesRead >= 0) {
baos.write(buffer, 0, bytesRead);
bytesRead = in.read(buffer);
}

byte[] bytes = baos.toByteArray();
return new String(bytes, "UTF-8");
}
}
//#full-server
10 changes: 1 addition & 9 deletions plugin-tester-java/src/main/resources/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,6 @@ akka.grpc.client {
"helloworld.GreeterService" {
host = 127.0.0.1
port = 8080
override-authority = foo.test.google.fr
ssl-config {
disabledKeyAlgorithms = [] // Allow weak certificates
trustManager {
stores = [
{path = certs/ca.pem, classpath = true, type = PEM}
]
}
}
use-tls = false
}
}
15 changes: 0 additions & 15 deletions plugin-tester-java/src/main/resources/certs/ca.pem

This file was deleted.

16 changes: 0 additions & 16 deletions plugin-tester-java/src/main/resources/certs/server1.key

This file was deleted.

16 changes: 0 additions & 16 deletions plugin-tester-java/src/main/resources/certs/server1.pem

This file was deleted.

9 changes: 1 addition & 8 deletions plugin-tester-scala/src/main/resources/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,6 @@ akka.grpc.client {
host = 127.0.0.1
port = 8080
override-authority = foo.test.google.fr
ssl-config {
disabledKeyAlgorithms = [] // Allow weak certificates
trustManager {
stores = [
{path = certs/ca.pem, classpath = true, type = PEM}
]
}
}
use-tls = false
}
}
15 changes: 0 additions & 15 deletions plugin-tester-scala/src/main/resources/certs/ca.pem

This file was deleted.

16 changes: 0 additions & 16 deletions plugin-tester-scala/src/main/resources/certs/server1.key

This file was deleted.

16 changes: 0 additions & 16 deletions plugin-tester-scala/src/main/resources/certs/server1.pem

This file was deleted.

Loading

0 comments on commit 9eec9cf

Please sign in to comment.