Skip to content

Commit

Permalink
Tls config (#21)
Browse files Browse the repository at this point in the history
* add tls config

* optimize tls config
  • Loading branch information
DanielLiu1123 committed Sep 30, 2023
1 parent 18a6035 commit 4ec64b7
Show file tree
Hide file tree
Showing 36 changed files with 386 additions and 52 deletions.
4 changes: 2 additions & 2 deletions examples/grpc-sample-api/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ dependencies {
api("io.grpc:grpc-testing-proto")
}

apply from: "$rootDir/deploy.gradle"
apply from: "$rootDir/protobuf.gradle"
apply from: "${rootDir}/gradle/deploy.gradle"
apply from: "${rootDir}/gradle/protobuf-with-pgv.gradle"
2 changes: 1 addition & 1 deletion examples/json-transcoder/webflux/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ dependencies {
testImplementation("org.springframework.boot:spring-boot-starter-test")
}

apply from: "${rootDir}/protobuf.gradle"
apply from: "${rootDir}/gradle/protobuf-with-pgv.gradle"
2 changes: 1 addition & 1 deletion examples/json-transcoder/webmvc/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ dependencies {
testImplementation("org.springframework.boot:spring-boot-starter-test")
}

apply from: "${rootDir}/protobuf.gradle"
apply from: "${rootDir}/gradle/protobuf-with-pgv.gradle"
2 changes: 1 addition & 1 deletion examples/simple/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ dependencies {
testImplementation(project(":grpc-starters:grpc-starter-test"))
}

apply from: "${rootDir}/protobuf.gradle"
apply from: "${rootDir}/gradle/protobuf-with-pgv.gradle"
16 changes: 16 additions & 0 deletions examples/tls/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
## Run Example

1. Generate certificates:

```shell
openssl genpkey -algorithm RSA -out ca.key
openssl req -new -key ca.key -out ca.csr
openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt

openssl genpkey -algorithm RSA -out server.key
openssl req -new -key server.key -out server.csr

openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -out server.crt
```

2. Run tests
13 changes: 13 additions & 0 deletions examples/tls/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
plugins {
id 'org.springframework.boot'
}

dependencies {
implementation(project(":grpc-starters:grpc-boot-starter"))
implementation("io.grpc:grpc-testing-proto")

testImplementation(project(":grpc-starters:grpc-starter-test"))
}

apply from: "${rootDir}/gradle/protobuf-with-pgv.gradle"

17 changes: 17 additions & 0 deletions examples/tls/src/main/java/com/freemanan/example/TLSApp.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.freemanan.example;

import com.freemanan.starter.grpc.client.EnableGrpcClients;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
* @author Freeman
*/
@SpringBootApplication
@EnableGrpcClients({"io.grpc"})
public class TLSApp {

public static void main(String[] args) {
SpringApplication.run(TLSApp.class, args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.freemanan.example.controller;

import io.grpc.stub.StreamObserver;
import io.grpc.testing.protobuf.SimpleRequest;
import io.grpc.testing.protobuf.SimpleResponse;
import io.grpc.testing.protobuf.SimpleServiceGrpc;
import org.springframework.stereotype.Controller;

/**
* @author Freeman
*/
@Controller
public class SimpleServiceController extends SimpleServiceGrpc.SimpleServiceImplBase {

@Override
public void unaryRpc(SimpleRequest request, StreamObserver<SimpleResponse> responseObserver) {
SimpleResponse response = SimpleResponse.newBuilder()
.setResponseMessage("Hi, I got your message: " + request.getRequestMessage())
.build();
responseObserver.onNext(response);
responseObserver.onCompleted();
}
}
13 changes: 13 additions & 0 deletions examples/tls/src/main/resources/application.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
grpc:
server:
reflection:
enabled: true
tls:
key-manager:
cert-chain: classpath:server.crt
private-key: classpath:server.key
client:
authority: localhost:${grpc.server.port:9090}
tls:
trust-manager:
root-certs: classpath:ca.crt
20 changes: 20 additions & 0 deletions examples/tls/src/main/resources/ca.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDOTCCAiECFCq3XQnKaNcPpk6aK5ZevTj/wuTiMA0GCSqGSIb3DQEBCwUAMFkx
CzAJBgNVBAYTAkNOMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRl
cm5ldCBXaWRnaXRzIFB0eSBMdGQxEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0yMzA5
MjkwNzEwMDRaFw0yMzEwMjkwNzEwMDRaMFkxCzAJBgNVBAYTAkNOMRMwEQYDVQQI
DApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQx
EjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBALIl80v24VGL5hfPjqe+AFeHRH9PaqIYygQlvlBkROfkg6UjBn4h/sr/bxNJ
NpdV1b2k/T5eyIgHFBKwd/LRcw4v15XCrCRcoJGdIctbKWRetA77C4Gx9c145BWE
gidgU3KawRfjwngbrezE6+SZlGFKRZER1o7/wSebyonQ1rO8cJqwdZOvsBgmhP59
d9banrHgB9gq7wTRmmZSHxEcXqUQ+9SJRmsM7hKTIZuGtcZ8YaJMBS36LWGNvxY7
PO+UzybhgtIXZGccrUx4B8qr10F7Y7hgcrumoPAwu9IyvSvQvRqn8II3xeCTGb6h
uuJo40cSaTSTZBe5ucTWt/qX+2MCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAHmZt
Wr6h3qBvUgaUbx/V7GLBXI+/8C8u0wEV17Ech6kzZMzbvSbVlOwnEYyyre7KgNKa
OWuzTKrtNNu7TDmnXaQiT2mckCiNokcy+dVuYEfSpKOZrRA8zxYU1DczwHBjmNAY
ZfopcFQIjXAjyZljBfx9+liq0r+TFvAOug9CPzCWYUopegqvuN2t2hM77getFm6U
NK4Ds0OGalVZXFjEkQ5wzsUcVAaEWVnjESEtgeYhit4NqCbMOZuPhp5CNCEhogDC
sUZLOcZhT0BReGbjP7iWEsMXzhT+oniHfQY1HmYnfooyD/5SDtbBUKM0Dnxpk366
H5Yd+n9LKMOR9CWU7A==
-----END CERTIFICATE-----
20 changes: 20 additions & 0 deletions examples/tls/src/main/resources/server.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDOTCCAiECFGXI9CSDVWVjt698kfJAdtvT+RX9MA0GCSqGSIb3DQEBCwUAMFkx
CzAJBgNVBAYTAkNOMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRl
cm5ldCBXaWRnaXRzIFB0eSBMdGQxEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0yMzA5
MjkwNzEwNTBaFw0yMzEwMjkwNzEwNTBaMFkxCzAJBgNVBAYTAkNOMRMwEQYDVQQI
DApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQx
EjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBAKRtx94G7wD3O8SZT1fMJO9+BLyNAa1noLH0RxLwprrV8MxEB+sgKm4EvfRW
ewDXv0k0Ofs1b6o20JiCIWRqDrfZmCAx6fWNZ23/rh1Ywc4PGFB9kOwbMQmhAf8b
Q4LTBqR+pISR6O/yg0ModshgOwodCLxI5FgxG6EWFhQMZv0pdvFIqFlSjbw9EHQc
EaO+ovwahux5NyWvufPp6ATWthcwgaNSD+8AVpdPgxfAjSZNTgsoHJldT7iyuMNA
7bQnBzogS2r2f1smnRH91zLRzM2UG5g3EvaEje+OWGp+QFymFYhlXY6BmBSXX3Sb
xE3SOQTEMHARz2iosqFRrChcFR8CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAc05G
5pCr37ZFLWYqi/NTyHfcpO7LdLJGmtSTFxn3jzRnvUFeWnxf6PWl/o7RFOHtJE5b
YGNgrBE33wMRf9RKzKMLUUsX8y2QmfSdlZ2TJPiWtFd5Mqb4lYCZIe4btuYVkNId
vcx1cYwEgyXcsIbumh/GnzKo5iW2/x+3vxlW5VhylgO6N8xy4/OHiRIq7EzqRPAM
YicDd2fPxeenVRezlsXGaLQ161TPI+AHXMe8uXICu5Z9F40juGikstMz/lgPLIxz
5J19nUwXLBM5qHQbpYeMFvB2lA+6NEGHdDYB8swqPNQK+ginhabsYXyLYUC8zPoa
eIB21mo5Gav/1z80hQ==
-----END CERTIFICATE-----
28 changes: 28 additions & 0 deletions examples/tls/src/main/resources/server.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCkbcfeBu8A9zvE
mU9XzCTvfgS8jQGtZ6Cx9EcS8Ka61fDMRAfrICpuBL30VnsA179JNDn7NW+qNtCY
giFkag632ZggMen1jWdt/64dWMHODxhQfZDsGzEJoQH/G0OC0wakfqSEkejv8oND
KHbIYDsKHQi8SORYMRuhFhYUDGb9KXbxSKhZUo28PRB0HBGjvqL8GobseTclr7nz
6egE1rYXMIGjUg/vAFaXT4MXwI0mTU4LKByZXU+4srjDQO20Jwc6IEtq9n9bJp0R
/dcy0czNlBuYNxL2hI3vjlhqfkBcphWIZV2OgZgUl190m8RN0jkExDBwEc9oqLKh
UawoXBUfAgMBAAECggEAAuP0Qf33xCgUcpx031ODT9DmWaNHz6govvLA2qaL/8YG
Olc8CREi9rIIT7FRRBzqWhRcHh/D2bIYNIU5+9LYypw9cb9wp0Kpz4PRmebMeAg6
5gX+KZPsH5dDs4243Hsng8tNdWWUVzBdAR+cQEVfdFFWAkDecWXF0i0L8GvzK0zd
P6HknfYHWdWORLKURvMARXxffmS/7DmQ/937MZzcf09DPMGP/AOMX7mdjkbJkC0D
rx9Ey+SU9bAMLbLwHezRLh+ElZr0lrKAT44ehrZa8mcuVnlqwoWxSKjYtoQ2Usmf
h5HhVFPzICo7nhyCbutfPUimZgZhxORqAsC1p6tR8QKBgQDUbY5il71UhBTU4ozB
yhg9Pc7JRCxY+3hH+trCRCcikWq0r636p4CIn0kZi7Worq/2eh5imwiw307pSgRk
ddz8lCQRjS/Cwopq9jRwOJfOusvB76bFCnRRlyOs3lfoUOgWvct+BfKMZNytU1SP
sbmNaXaBDZBOURBLpK8CT1YSLwKBgQDGJ9L05CqHmqRtFxTBayx6TQKNJ/TAnc5W
tHyMZL1g2FQEkxKkQWS7Zx7tz8P38ZEaKA21F/YXBJ7pUZuJEFsBSq+26C/MtaaG
23wBVBNg8xB6eWXyHOYYfbggdg5uGB+yp0by7kHctm1T/w3T9qqHfML45d6LqQ3D
jN0KB9EgEQKBgCNfbuNKAzPsno9ofinS3kBsZ1+qY3wZu8i4o+7PbHjcIBmgW2cu
tz+IzqJbWk+Rbymq4h5nVIYnWTuNoLedzMOeY3csvHRA8s2m28qIEfdRsZZEss+C
0yW29jDWAWtk9ZC74APHN8FbFkgiZSVcYdqDYkFRIeN4qi7+aEoJLfrvAoGAGPvW
bkgCULyftJ1vYX+oyPbCtpduFYcQCACTn4PoGLjNxxHgDNOt5q72yFckxzMu71RT
fhy6S2aqvpIqgRqNztji1LXrqOzSRTiRJv25v8SFtFtwDhm0rSvUtksMQLdL79OF
b4W4yiI6IJgM30e/cnu5fXZGG+fBs4EkMWqQ5HECgYBLmGwa9I1UnbHncieCBEDU
xyiydebDHFX+ZP5ecTU+5Ob5IBso1bWnsoOo/N5Gb86YX3W/TmECnE0yOz2RtPR+
1qzSb1s/IurcHpPNU4JMakiLRyeVX0SfResJcbFkbfwvvg02d03cBPHBYZ/8WSH4
bkF/XFMlYZZl/C8qNGsKOQ==
-----END PRIVATE KEY-----
29 changes: 29 additions & 0 deletions examples/tls/src/test/java/com/freemanan/example/TLSAppTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.freemanan.example;

import static org.assertj.core.api.Assertions.assertThat;

import io.grpc.testing.protobuf.SimpleRequest;
import io.grpc.testing.protobuf.SimpleServiceGrpc;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest(
properties = {
"grpc.test.enabled=false",
"grpc.server.port=12345",
"grpc.client.authority=localhost:12345",
})
class TLSAppTest {

@Autowired
SimpleServiceGrpc.SimpleServiceBlockingStub simpleServiceBlockingStub;

@Test
void testUnaryRpc() {
String responseMessage = simpleServiceBlockingStub
.unaryRpc(SimpleRequest.newBuilder().setRequestMessage("Hello").build())
.getResponseMessage();
assertThat(responseMessage).isEqualTo("Hi, I got your message: Hello");
}
}
2 changes: 1 addition & 1 deletion examples/user/user-api/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ dependencies {
implementation(project(":grpc-starters:grpc-starter-validation"))
}

apply from: "${rootDir}/protobuf.gradle"
apply from: "${rootDir}/gradle/protobuf-with-pgv.gradle"

sourceSets {
main {
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ dependencies {
testImplementation("org.springframework.cloud:spring-cloud-context")
}

apply from: "${rootDir}/deploy.gradle"
apply from: "${rootDir}/gradle/deploy.gradle"
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@

import com.freemanan.starter.grpc.client.exception.MissingChannelConfigurationException;
import io.grpc.ClientInterceptor;
import io.grpc.Grpc;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.Metadata;
import io.grpc.TlsChannelCredentials;
import io.grpc.inprocess.InProcessChannelBuilder;
import io.grpc.stub.MetadataUtils;
import lombok.SneakyThrows;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.util.Assert;
Expand Down Expand Up @@ -43,20 +46,7 @@ public ManagedChannel create() {
}

private ManagedChannel buildChannel(GrpcClientProperties.Channel channelConfig) {
ManagedChannelBuilder<?> builder;
if (channelConfig.getInProcess() == null) {
if (!StringUtils.hasText(channelConfig.getAuthority())) {
throw new MissingChannelConfigurationException(stubClass);
}
builder = ManagedChannelBuilder.forTarget(channelConfig.getAuthority());
} else {
Assert.hasText(
channelConfig.getInProcess().getName(),
"Not configure in-process name for stub: " + stubClass.getName());
builder = InProcessChannelBuilder.forName(
channelConfig.getInProcess().getName())
.directExecutor();
}
ManagedChannelBuilder<?> builder = getManagedChannelBuilder(channelConfig);

// set max message size and max metadata size
builder.maxInboundMessageSize((int) channelConfig.getMaxMessageSize().toBytes());
Expand All @@ -78,9 +68,6 @@ private ManagedChannel buildChannel(GrpcClientProperties.Channel channelConfig)
.sorted(AnnotationAwareOrderComparator.INSTANCE.reversed())
.forEach(builder::intercept);

// use plaintext
builder.usePlaintext();

// apply customizers
beanFactory
.getBeanProvider(GrpcChannelCustomizer.class)
Expand All @@ -89,4 +76,41 @@ private ManagedChannel buildChannel(GrpcClientProperties.Channel channelConfig)

return builder.build();
}

@SneakyThrows
private ManagedChannelBuilder<?> getManagedChannelBuilder(GrpcClientProperties.Channel channelConfig) {
if (channelConfig.getInProcess() == null) {
if (!StringUtils.hasText(channelConfig.getAuthority())) {
throw new MissingChannelConfigurationException(stubClass);
}
GrpcClientProperties.Tls tls = channelConfig.getTls();
if (tls == null) {
return ManagedChannelBuilder.forTarget(channelConfig.getAuthority())
.usePlaintext();
}
TlsChannelCredentials.Builder tlsBuilder = TlsChannelCredentials.newBuilder();
if (tls.getKeyManager() != null) {
GrpcClientProperties.Tls.KeyManager keyManager = tls.getKeyManager();
if (StringUtils.hasText(keyManager.getPrivateKeyPassword())) {
tlsBuilder.keyManager(
keyManager.getCertChain().getInputStream(),
keyManager.getPrivateKey().getInputStream(),
keyManager.getPrivateKeyPassword());
} else {
tlsBuilder.keyManager(
keyManager.getCertChain().getInputStream(),
keyManager.getPrivateKey().getInputStream());
}
}
if (tls.getTrustManager() != null) {
tlsBuilder.trustManager(tls.getTrustManager().getRootCerts().getInputStream());
}
return Grpc.newChannelBuilder(channelConfig.getAuthority(), tlsBuilder.build());
}
Assert.hasText(
channelConfig.getInProcess().getName(),
"Not configure in-process name for stub: " + stubClass.getName());
return InProcessChannelBuilder.forName(channelConfig.getInProcess().getName())
.directExecutor();
}
}
Loading

0 comments on commit 4ec64b7

Please sign in to comment.