mirror of https://github.com/grpc/grpc-java.git
binder: Ensure the security interceptor is always closest to the actual transport. (#9716)
This commit is contained in:
parent
58ba73205a
commit
f082151fb5
|
|
@ -29,9 +29,12 @@ import com.google.common.base.Function;
|
||||||
import com.google.protobuf.Empty;
|
import com.google.protobuf.Empty;
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.CallOptions;
|
||||||
import io.grpc.ManagedChannel;
|
import io.grpc.ManagedChannel;
|
||||||
|
import io.grpc.Metadata;
|
||||||
import io.grpc.MethodDescriptor;
|
import io.grpc.MethodDescriptor;
|
||||||
import io.grpc.Server;
|
import io.grpc.Server;
|
||||||
|
import io.grpc.ServerCall;
|
||||||
import io.grpc.ServerCallHandler;
|
import io.grpc.ServerCallHandler;
|
||||||
|
import io.grpc.ServerInterceptor;
|
||||||
import io.grpc.ServerServiceDefinition;
|
import io.grpc.ServerServiceDefinition;
|
||||||
import io.grpc.Status;
|
import io.grpc.Status;
|
||||||
import io.grpc.StatusRuntimeException;
|
import io.grpc.StatusRuntimeException;
|
||||||
|
|
@ -59,6 +62,7 @@ public final class BinderSecurityTest {
|
||||||
@Nullable ManagedChannel channel;
|
@Nullable ManagedChannel channel;
|
||||||
Map<String, MethodDescriptor<Empty, Empty>> methods = new HashMap<>();
|
Map<String, MethodDescriptor<Empty, Empty>> methods = new HashMap<>();
|
||||||
List<MethodDescriptor<Empty, Empty>> calls = new ArrayList<>();
|
List<MethodDescriptor<Empty, Empty>> calls = new ArrayList<>();
|
||||||
|
CountingServerInterceptor countingServerInterceptor;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setupServiceDefinitionsAndMethods() {
|
public void setupServiceDefinitionsAndMethods() {
|
||||||
|
|
@ -86,6 +90,7 @@ public final class BinderSecurityTest {
|
||||||
}
|
}
|
||||||
serviceDefinitions.add(builder.build());
|
serviceDefinitions.add(builder.build());
|
||||||
}
|
}
|
||||||
|
countingServerInterceptor = new CountingServerInterceptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
|
@ -120,6 +125,7 @@ public final class BinderSecurityTest {
|
||||||
ServerSecurityPolicy serverPolicy) {
|
ServerSecurityPolicy serverPolicy) {
|
||||||
BinderServerBuilder serverBuilder = BinderServerBuilder.forAddress(listenAddr, receiver);
|
BinderServerBuilder serverBuilder = BinderServerBuilder.forAddress(listenAddr, receiver);
|
||||||
serverBuilder.securityPolicy(serverPolicy);
|
serverBuilder.securityPolicy(serverPolicy);
|
||||||
|
serverBuilder.intercept(countingServerInterceptor);
|
||||||
|
|
||||||
for (ServerServiceDefinition serviceDefinition : serviceDefinitions) {
|
for (ServerServiceDefinition serviceDefinition : serviceDefinitions) {
|
||||||
serverBuilder.addService(serviceDefinition);
|
serverBuilder.addService(serviceDefinition);
|
||||||
|
|
@ -195,6 +201,27 @@ public final class BinderSecurityTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSecurityInterceptorIsClosestToTransport() throws Exception {
|
||||||
|
createChannel(
|
||||||
|
ServerSecurityPolicy.newBuilder()
|
||||||
|
.servicePolicy("foo", policy((uid) -> true))
|
||||||
|
.servicePolicy("bar", policy((uid) -> false))
|
||||||
|
.servicePolicy("baz", policy((uid) -> false))
|
||||||
|
.build(),
|
||||||
|
SecurityPolicies.internalOnly());
|
||||||
|
assertThat(countingServerInterceptor.numInterceptedCalls).isEqualTo(0);
|
||||||
|
for (MethodDescriptor<Empty, Empty> method : methods.values()) {
|
||||||
|
try {
|
||||||
|
ClientCalls.blockingUnaryCall(channel, method, CallOptions.DEFAULT, null);
|
||||||
|
} catch (StatusRuntimeException sre) {
|
||||||
|
// Ignore.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Only the foo calls should have made it to the user interceptor.
|
||||||
|
assertThat(countingServerInterceptor.numInterceptedCalls).isEqualTo(2);
|
||||||
|
}
|
||||||
|
|
||||||
private static SecurityPolicy policy(Function<Integer, Boolean> func) {
|
private static SecurityPolicy policy(Function<Integer, Boolean> func) {
|
||||||
return new SecurityPolicy() {
|
return new SecurityPolicy() {
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -203,4 +230,17 @@ public final class BinderSecurityTest {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final class CountingServerInterceptor implements ServerInterceptor {
|
||||||
|
int numInterceptedCalls;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
|
||||||
|
ServerCall<ReqT, RespT> call,
|
||||||
|
Metadata headers,
|
||||||
|
ServerCallHandler<ReqT, RespT> next) {
|
||||||
|
numInterceptedCalls += 1;
|
||||||
|
return next.startCall(call, headers);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,7 @@ public final class BinderServerBuilder
|
||||||
SharedResourcePool.forResource(GrpcUtil.TIMER_SERVICE);
|
SharedResourcePool.forResource(GrpcUtil.TIMER_SERVICE);
|
||||||
private ServerSecurityPolicy securityPolicy;
|
private ServerSecurityPolicy securityPolicy;
|
||||||
private InboundParcelablePolicy inboundParcelablePolicy;
|
private InboundParcelablePolicy inboundParcelablePolicy;
|
||||||
|
private boolean isBuilt;
|
||||||
|
|
||||||
private BinderServerBuilder(
|
private BinderServerBuilder(
|
||||||
AndroidComponentAddress listenAddress,
|
AndroidComponentAddress listenAddress,
|
||||||
|
|
@ -107,8 +108,6 @@ public final class BinderServerBuilder
|
||||||
// Disable stats and tracing by default.
|
// Disable stats and tracing by default.
|
||||||
serverImplBuilder.setStatsEnabled(false);
|
serverImplBuilder.setStatsEnabled(false);
|
||||||
serverImplBuilder.setTracingEnabled(false);
|
serverImplBuilder.setTracingEnabled(false);
|
||||||
|
|
||||||
BinderTransportSecurity.installAuthInterceptor(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -177,6 +176,11 @@ public final class BinderServerBuilder
|
||||||
*/
|
*/
|
||||||
@Override // For javadoc refinement only.
|
@Override // For javadoc refinement only.
|
||||||
public Server build() {
|
public Server build() {
|
||||||
|
// Since we install a final interceptor here, we need to ensure we're only built once.
|
||||||
|
checkState(!isBuilt, "BinderServerBuilder can only be used to build one server instance.");
|
||||||
|
isBuilt = true;
|
||||||
|
// We install the security interceptor last, so it's closest to the transport.
|
||||||
|
BinderTransportSecurity.installAuthInterceptor(this);
|
||||||
return super.build();
|
return super.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue