Skip to content

Commit 8e50ad9

Browse files
committed
Fixup: 12493 Fix callcredentials to not apply instead of erroring out and add test coverage
1 parent 1d4e48b commit 8e50ad9

File tree

2 files changed

+141
-6
lines changed

2 files changed

+141
-6
lines changed

xds/src/main/java/io/grpc/xds/internal/grpcservice/GrpcServiceConfigParser.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import io.grpc.InsecureChannelCredentials;
3030
import io.grpc.Metadata;
3131
import io.grpc.SecurityLevel;
32-
import io.grpc.Status;
3332
import io.grpc.alts.GoogleDefaultChannelCredentials;
3433
import io.grpc.auth.MoreCallCredentials;
3534
import io.grpc.xds.XdsChannelCredentials;
@@ -258,12 +257,11 @@ private static final class SecurityAwareAccessTokenCredentials extends CallCrede
258257
@Override
259258
public void applyRequestMetadata(RequestInfo requestInfo, Executor appExecutor,
260259
MetadataApplier applier) {
261-
if (requestInfo.getSecurityLevel() != SecurityLevel.PRIVACY_AND_INTEGRITY) {
262-
applier.fail(Status.UNAUTHENTICATED.withDescription(
263-
"OAuth2 credentials require connection with PRIVACY_AND_INTEGRITY security level"));
264-
return;
260+
if (requestInfo.getSecurityLevel() == SecurityLevel.PRIVACY_AND_INTEGRITY) {
261+
delegate.applyRequestMetadata(requestInfo, appExecutor, applier);
262+
} else {
263+
applier.apply(new Metadata());
265264
}
266-
delegate.applyRequestMetadata(requestInfo, appExecutor, applier);
267265
}
268266
}
269267

xds/src/test/java/io/grpc/xds/internal/grpcservice/GrpcServiceConfigParserTest.java

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,4 +387,141 @@ public void parseGoogleGrpcConfig_unsupportedScheme() {
387387
assertThat(exception).hasMessageThat()
388388
.contains("Target URI scheme is not resolvable");
389389
}
390+
391+
static class RecordingMetadataApplier extends io.grpc.CallCredentials.MetadataApplier {
392+
boolean applied = false;
393+
boolean failed = false;
394+
io.grpc.Metadata appliedHeaders = null;
395+
396+
@Override
397+
public void apply(io.grpc.Metadata headers) {
398+
applied = true;
399+
appliedHeaders = headers;
400+
}
401+
402+
@Override
403+
public void fail(io.grpc.Status status) {
404+
failed = true;
405+
}
406+
}
407+
408+
static class FakeRequestInfo extends io.grpc.CallCredentials.RequestInfo {
409+
private final io.grpc.SecurityLevel securityLevel;
410+
private final io.grpc.MethodDescriptor<?, ?> methodDescriptor;
411+
412+
FakeRequestInfo(io.grpc.SecurityLevel securityLevel) {
413+
this.securityLevel = securityLevel;
414+
this.methodDescriptor = io.grpc.MethodDescriptor.<Void, Void>newBuilder()
415+
.setType(io.grpc.MethodDescriptor.MethodType.UNARY)
416+
.setFullMethodName("test_service/test_method")
417+
.setRequestMarshaller(new NoopMarshaller<Void>())
418+
.setResponseMarshaller(new NoopMarshaller<Void>())
419+
.build();
420+
}
421+
422+
private static class NoopMarshaller<T> implements io.grpc.MethodDescriptor.Marshaller<T> {
423+
@Override
424+
public java.io.InputStream stream(T value) {
425+
return null;
426+
}
427+
428+
@Override
429+
public T parse(java.io.InputStream stream) {
430+
return null;
431+
}
432+
}
433+
434+
@Override
435+
public io.grpc.MethodDescriptor<?, ?> getMethodDescriptor() {
436+
return methodDescriptor;
437+
}
438+
439+
@Override
440+
public io.grpc.SecurityLevel getSecurityLevel() {
441+
return securityLevel;
442+
}
443+
444+
@Override
445+
public String getAuthority() {
446+
return "dummy-authority";
447+
}
448+
449+
@Override
450+
public io.grpc.Attributes getTransportAttrs() {
451+
return io.grpc.Attributes.EMPTY;
452+
}
453+
}
454+
455+
456+
@Test
457+
public void securityAwareCredentials_secureConnection_appliesToken() throws Exception {
458+
Any insecureCreds = Any.pack(InsecureCredentials.getDefaultInstance());
459+
Any accessTokenCreds =
460+
Any.pack(AccessTokenCredentials.newBuilder().setToken("test_token").build());
461+
GrpcService.GoogleGrpc googleGrpc = GrpcService.GoogleGrpc.newBuilder()
462+
.setTargetUri("test_uri")
463+
.addChannelCredentialsPlugin(insecureCreds)
464+
.addCallCredentialsPlugin(accessTokenCreds)
465+
.build();
466+
GrpcService grpcService = GrpcService.newBuilder().setGoogleGrpc(googleGrpc).build();
467+
468+
GrpcServiceConfig config = GrpcServiceConfigParser.parse(grpcService,
469+
io.grpc.xds.internal.grpcservice.GrpcServiceXdsContextTestUtil.dummyProvider());
470+
471+
io.grpc.CallCredentials creds = config.googleGrpc().callCredentials().get();
472+
RecordingMetadataApplier applier = new RecordingMetadataApplier();
473+
java.util.concurrent.CountDownLatch latch = new java.util.concurrent.CountDownLatch(1);
474+
475+
creds.applyRequestMetadata(
476+
new FakeRequestInfo(io.grpc.SecurityLevel.PRIVACY_AND_INTEGRITY),
477+
Runnable::run, // Use direct executor to avoid async issues in test
478+
new io.grpc.CallCredentials.MetadataApplier() {
479+
@Override
480+
public void apply(io.grpc.Metadata headers) {
481+
applier.apply(headers);
482+
latch.countDown();
483+
}
484+
485+
@Override
486+
public void fail(io.grpc.Status status) {
487+
applier.fail(status);
488+
latch.countDown();
489+
}
490+
});
491+
492+
latch.await(5, java.util.concurrent.TimeUnit.SECONDS);
493+
assertThat(applier.applied).isTrue();
494+
assertThat(applier.appliedHeaders.get(
495+
io.grpc.Metadata.Key.of("Authorization", io.grpc.Metadata.ASCII_STRING_MARSHALLER)))
496+
.isEqualTo("Bearer test_token");
497+
}
498+
499+
@Test
500+
public void securityAwareCredentials_insecureConnection_appliesEmptyMetadata() throws Exception {
501+
Any insecureCreds = Any.pack(InsecureCredentials.getDefaultInstance());
502+
Any accessTokenCreds =
503+
Any.pack(AccessTokenCredentials.newBuilder().setToken("test_token").build());
504+
GrpcService.GoogleGrpc googleGrpc = GrpcService.GoogleGrpc.newBuilder()
505+
.setTargetUri("test_uri")
506+
.addChannelCredentialsPlugin(insecureCreds)
507+
.addCallCredentialsPlugin(accessTokenCreds)
508+
.build();
509+
GrpcService grpcService = GrpcService.newBuilder().setGoogleGrpc(googleGrpc).build();
510+
511+
GrpcServiceConfig config = GrpcServiceConfigParser.parse(grpcService,
512+
io.grpc.xds.internal.grpcservice.GrpcServiceXdsContextTestUtil.dummyProvider());
513+
514+
io.grpc.CallCredentials creds = config.googleGrpc().callCredentials().get();
515+
RecordingMetadataApplier applier = new RecordingMetadataApplier();
516+
517+
creds.applyRequestMetadata(
518+
new FakeRequestInfo(io.grpc.SecurityLevel.NONE),
519+
Runnable::run,
520+
applier);
521+
522+
assertThat(applier.applied).isTrue();
523+
assertThat(applier.appliedHeaders.get(
524+
io.grpc.Metadata.Key.of("Authorization", io.grpc.Metadata.ASCII_STRING_MARSHALLER)))
525+
.isNull();
526+
}
390527
}

0 commit comments

Comments
 (0)