diff --git a/samples/grpc-tomcat-secure/src/test/java/org/springframework/grpc/sample/GrpcServerApplicationTests.java b/samples/grpc-tomcat-secure/src/test/java/org/springframework/grpc/sample/GrpcServerApplicationTests.java index d2af82c..2278dbe 100644 --- a/samples/grpc-tomcat-secure/src/test/java/org/springframework/grpc/sample/GrpcServerApplicationTests.java +++ b/samples/grpc-tomcat-secure/src/test/java/org/springframework/grpc/sample/GrpcServerApplicationTests.java @@ -3,6 +3,8 @@ package org.springframework.grpc.sample; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; +import java.util.List; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.junit.jupiter.api.Test; @@ -69,10 +71,8 @@ public class GrpcServerApplicationTests { @Bean @Lazy SimpleGrpc.SimpleBlockingStub basic(GrpcChannelFactory channels, @LocalServerPort int port) { - return SimpleGrpc.newBlockingStub(channels.createChannel("0.0.0.0:" + port, - ChannelBuilderOptions.defaults() - .withCustomizer((authority, channel) -> channel - .intercept(new BasicAuthenticationInterceptor("user", "user"))))); + return SimpleGrpc.newBlockingStub(channels.createChannel("0.0.0.0:" + port, ChannelBuilderOptions.defaults() + .withInterceptors(List.of(new BasicAuthenticationInterceptor("user", "user"))))); } @Bean diff --git a/spring-grpc-core/src/main/java/org/springframework/grpc/client/security/BearerTokenAuthenticationInterceptor.java b/spring-grpc-core/src/main/java/org/springframework/grpc/client/security/BearerTokenAuthenticationInterceptor.java new file mode 100644 index 0000000..144f7d2 --- /dev/null +++ b/spring-grpc-core/src/main/java/org/springframework/grpc/client/security/BearerTokenAuthenticationInterceptor.java @@ -0,0 +1,58 @@ +/* + * Copyright 2024-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.grpc.client.security; + +import java.util.function.Supplier; + +import org.springframework.grpc.server.security.GrpcSecurity; + +import io.grpc.CallOptions; +import io.grpc.Channel; +import io.grpc.ClientCall; +import io.grpc.ClientInterceptor; +import io.grpc.ForwardingClientCall.SimpleForwardingClientCall; +import io.grpc.MethodDescriptor; + +/** + * An interceptor that adds bearer token authentication headers to gRPC client calls. + * + * @author Dave Syer + */ +public class BearerTokenAuthenticationInterceptor implements ClientInterceptor { + + private final Supplier token; + + public BearerTokenAuthenticationInterceptor(String token) { + this(() -> token); + } + + public BearerTokenAuthenticationInterceptor(Supplier token) { + this.token = token; + } + + @Override + public ClientCall interceptCall(MethodDescriptor method, + CallOptions callOptions, Channel next) { + return new SimpleForwardingClientCall(next.newCall(method, callOptions)) { + public void start(ClientCall.Listener responseListener, io.grpc.Metadata headers) { + headers.put(GrpcSecurity.AUTHORIZATION_KEY, + "Bearer " + BearerTokenAuthenticationInterceptor.this.token.get()); + super.start(responseListener, headers); + }; + }; + } + +}