Add client auth enum to ssl configuration

This commit is contained in:
Dave Syer
2024-11-04 09:49:01 +00:00
parent d24e80aedd
commit 148e1d1e23
6 changed files with 90 additions and 39 deletions

View File

@@ -18,6 +18,7 @@ package org.springframework.grpc.sample;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
@@ -119,6 +120,23 @@ class GrpcServerIntegrationTests {
}
@Nested
@SpringBootTest(properties = { "spring.grpc.server.port=0", "spring.grpc.server.ssl.client-auth=REQUIRE",
"spring.grpc.client.channels.test-channel.address=static://0.0.0.0:${local.grpc.port}",
"spring.grpc.client.channels.test-channel.negotiation-type=TLS",
"spring.grpc.client.channels.test-channel.secure=false" })
@ActiveProfiles("ssl")
@DirtiesContext
@Disabled("Requires client certificate")
class ServerWithClientAuth {
@Test
void clientChannelWithSsl(@Autowired GrpcChannelFactory channels) {
assertThatResponseIsServedToChannel(channels.createChannel("test-channel").build());
}
}
private void assertThatResponseIsServedToChannel(ManagedChannel clientChannel) {
SimpleGrpc.SimpleBlockingStub client = SimpleGrpc.newBlockingStub(clientChannel);
HelloReply response = client.sayHello(HelloRequest.newBuilder().setName("Alien").build());

View File

@@ -21,6 +21,13 @@ import java.util.List;
import java.util.Objects;
import java.util.Set;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManagerFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.grpc.internal.GrpcUtils;
import com.google.common.collect.Lists;
import io.grpc.Grpc;
@@ -30,10 +37,9 @@ import io.grpc.ServerBuilder;
import io.grpc.ServerCredentials;
import io.grpc.ServerProvider;
import io.grpc.ServerServiceDefinition;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.grpc.internal.GrpcUtils;
import io.grpc.TlsServerCredentials;
import io.grpc.TlsServerCredentials.Builder;
import io.grpc.TlsServerCredentials.ClientAuth;
/**
* Default implementation for {@link GrpcServerFactory gRPC service factories}.
@@ -56,11 +62,25 @@ public class DefaultGrpcServerFactory<T extends ServerBuilder<T>> implements Grp
private final List<ServerBuilderCustomizer<T>> serverBuilderCustomizers;
private KeyManagerFactory keyManager;
private TrustManagerFactory trustManager;
private ClientAuth clientAuth;
public DefaultGrpcServerFactory(String address, List<ServerBuilderCustomizer<T>> serverBuilderCustomizers) {
this.address = address;
this.serverBuilderCustomizers = Objects.requireNonNull(serverBuilderCustomizers, "serverBuilderCustomizers");
}
public DefaultGrpcServerFactory(String address, List<ServerBuilderCustomizer<T>> serverBuilderCustomizers,
KeyManagerFactory keyManager, TrustManagerFactory trustManager, ClientAuth clientAuth) {
this(address, serverBuilderCustomizers);
this.keyManager = keyManager;
this.trustManager = trustManager;
this.clientAuth = clientAuth;
}
protected String address() {
return this.address;
}
@@ -99,7 +119,17 @@ public class DefaultGrpcServerFactory<T extends ServerBuilder<T>> implements Grp
* @return some server credentials (default is insecure)
*/
protected ServerCredentials credentials() {
return InsecureServerCredentials.create();
if (this.keyManager == null || port() == -1) {
return InsecureServerCredentials.create();
}
Builder builder = TlsServerCredentials.newBuilder().keyManager(this.keyManager.getKeyManagers());
if (this.trustManager != null) {
builder.trustManager(this.trustManager.getTrustManagers());
}
if (this.clientAuth != null) {
builder.clientAuth(this.clientAuth);
}
return builder.build();
}
/**

View File

@@ -19,9 +19,12 @@ package org.springframework.grpc.server;
import java.util.List;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManagerFactory;
import io.grpc.ServerCredentials;
import io.grpc.TlsServerCredentials;
import io.grpc.TlsServerCredentials.Builder;
import io.grpc.TlsServerCredentials.ClientAuth;
import io.grpc.netty.NettyServerBuilder;
import io.netty.channel.epoll.EpollEventLoopGroup;
import io.netty.channel.epoll.EpollServerDomainSocketChannel;
@@ -35,12 +38,10 @@ import io.netty.channel.unix.DomainSocketAddress;
*/
public class NettyGrpcServerFactory extends DefaultGrpcServerFactory<NettyServerBuilder> {
private KeyManagerFactory keyManager;
public NettyGrpcServerFactory(String address, KeyManagerFactory keyManager,
List<ServerBuilderCustomizer<NettyServerBuilder>> serverBuilderCustomizers) {
super(address, serverBuilderCustomizers);
this.keyManager = keyManager;
public NettyGrpcServerFactory(String address,
List<ServerBuilderCustomizer<NettyServerBuilder>> serverBuilderCustomizers, KeyManagerFactory keyManager,
TrustManagerFactory trustManager, ClientAuth clientAuth) {
super(address, serverBuilderCustomizers, keyManager, trustManager, clientAuth);
}
@Override
@@ -56,12 +57,4 @@ public class NettyGrpcServerFactory extends DefaultGrpcServerFactory<NettyServer
return super.newServerBuilder();
}
@Override
protected ServerCredentials credentials() {
if (this.keyManager == null || port() == -1) {
return super.credentials();
}
return TlsServerCredentials.newBuilder().keyManager(this.keyManager.getKeyManagers()).build();
}
}

View File

@@ -19,9 +19,9 @@ package org.springframework.grpc.server;
import java.util.List;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManagerFactory;
import io.grpc.ServerCredentials;
import io.grpc.TlsServerCredentials;
import io.grpc.TlsServerCredentials.ClientAuth;
import io.grpc.netty.shaded.io.grpc.netty.NettyServerBuilder;
import io.grpc.netty.shaded.io.netty.channel.epoll.EpollEventLoopGroup;
import io.grpc.netty.shaded.io.netty.channel.epoll.EpollServerDomainSocketChannel;
@@ -35,12 +35,10 @@ import io.grpc.netty.shaded.io.netty.channel.unix.DomainSocketAddress;
*/
public class ShadedNettyGrpcServerFactory extends DefaultGrpcServerFactory<NettyServerBuilder> {
private KeyManagerFactory keyManager;
public ShadedNettyGrpcServerFactory(String address, KeyManagerFactory keyManager,
List<ServerBuilderCustomizer<NettyServerBuilder>> serverBuilderCustomizers) {
super(address, serverBuilderCustomizers);
this.keyManager = keyManager;
public ShadedNettyGrpcServerFactory(String address,
List<ServerBuilderCustomizer<NettyServerBuilder>> serverBuilderCustomizers, KeyManagerFactory keyManager,
TrustManagerFactory trustManager, ClientAuth clientAuth) {
super(address, serverBuilderCustomizers, keyManager, trustManager, clientAuth);
}
@Override
@@ -56,12 +54,4 @@ public class ShadedNettyGrpcServerFactory extends DefaultGrpcServerFactory<Netty
return super.newServerBuilder();
}
@Override
protected ServerCredentials credentials() {
if (this.keyManager == null || port() == -1) {
return super.credentials();
}
return TlsServerCredentials.newBuilder().keyManager(this.keyManager.getKeyManagers()).build();
}
}

View File

@@ -19,6 +19,7 @@ package org.springframework.grpc.autoconfigure.server;
import java.util.List;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManagerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -56,12 +57,14 @@ class GrpcServerFactoryConfigurations {
List<ServerBuilderCustomizer<io.grpc.netty.shaded.io.grpc.netty.NettyServerBuilder>> builderCustomizers = List
.of(mapper::customizeServerBuilder, serverBuilderCustomizers::customize);
KeyManagerFactory keyManager = null;
TrustManagerFactory trustManager = null;
if (properties.getSsl().isEnabled()) {
SslBundle bundle = bundles.getBundle(properties.getSsl().getBundle());
keyManager = bundle.getManagers().getKeyManagerFactory();
trustManager = bundle.getManagers().getTrustManagerFactory();
}
ShadedNettyGrpcServerFactory factory = new ShadedNettyGrpcServerFactory(properties.getAddress(), keyManager,
builderCustomizers);
ShadedNettyGrpcServerFactory factory = new ShadedNettyGrpcServerFactory(properties.getAddress(),
builderCustomizers, keyManager, trustManager, properties.getSsl().getClientAuth());
grpcServicesDiscoverer.findServices().forEach(factory::addService);
return factory;
}
@@ -82,12 +85,14 @@ class GrpcServerFactoryConfigurations {
List<ServerBuilderCustomizer<NettyServerBuilder>> builderCustomizers = List
.of(mapper::customizeServerBuilder, serverBuilderCustomizers::customize);
KeyManagerFactory keyManager = null;
TrustManagerFactory trustManager = null;
if (properties.getSsl().isEnabled()) {
SslBundle bundle = bundles.getBundle(properties.getSsl().getBundle());
keyManager = bundle.getManagers().getKeyManagerFactory();
trustManager = bundle.getManagers().getTrustManagerFactory();
}
NettyGrpcServerFactory factory = new NettyGrpcServerFactory(properties.getAddress(), keyManager,
builderCustomizers);
NettyGrpcServerFactory factory = new NettyGrpcServerFactory(properties.getAddress(), builderCustomizers,
keyManager, trustManager, properties.getSsl().getClientAuth());
grpcServicesDiscoverer.findServices().forEach(factory::addService);
return factory;
}

View File

@@ -25,6 +25,8 @@ import org.springframework.grpc.internal.GrpcUtils;
import org.springframework.util.unit.DataSize;
import org.springframework.util.unit.DataUnit;
import io.grpc.TlsServerCredentials.ClientAuth;
@ConfigurationProperties(prefix = "spring.grpc.server")
public class GrpcServerProperties {
@@ -253,6 +255,11 @@ public class GrpcServerProperties {
*/
private Boolean enabled;
/**
* Client authentication mode.
*/
private ClientAuth clientAuth = ClientAuth.NONE;
/**
* SSL bundle name.
*/
@@ -284,6 +291,14 @@ public class GrpcServerProperties {
this.bundle = bundle;
}
public void setClientAuth(ClientAuth clientAuth) {
this.clientAuth = clientAuth;
}
public ClientAuth getClientAuth() {
return clientAuth;
}
}
}