diff --git a/src/csharp/Grpc.Auth/GoogleCredential.cs b/src/csharp/Grpc.Auth/GoogleCredential.cs index 8d5e543a216540767a8f81624dd33527c29eecb1..7edf19ed67aae36fd5023d3ef7fcf5ca603edb9b 100644 --- a/src/csharp/Grpc.Auth/GoogleCredential.cs +++ b/src/csharp/Grpc.Auth/GoogleCredential.cs @@ -35,8 +35,11 @@ using System; using System.Collections.Generic; using System.IO; using System.Security.Cryptography; +using System.Threading; +using System.Threading.Tasks; using Google.Apis.Auth.OAuth2; +using Google.Apis.Auth.OAuth2.Responses; using Newtonsoft.Json.Linq; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Security; @@ -100,6 +103,19 @@ namespace Grpc.Auth return new GoogleCredential(serviceCredential); } + public Task<bool> RequestAccessTokenAsync(CancellationToken taskCancellationToken) + { + return credential.RequestAccessTokenAsync(taskCancellationToken); + } + + public TokenResponse Token + { + get + { + return credential.Token; + } + } + internal ServiceCredential InternalCredential { get diff --git a/src/csharp/Grpc.Core.Tests/Internal/MetadataArraySafeHandleTest.cs b/src/csharp/Grpc.Core.Tests/Internal/MetadataArraySafeHandleTest.cs index 320423b245d2dd68ec175867efc21b6707c2d5a3..e03e20c4f70999328442ae47477f50b572bbb96f 100644 --- a/src/csharp/Grpc.Core.Tests/Internal/MetadataArraySafeHandleTest.cs +++ b/src/csharp/Grpc.Core.Tests/Internal/MetadataArraySafeHandleTest.cs @@ -51,7 +51,8 @@ namespace Grpc.Core.Internal.Tests [Test] public void CreateAndDestroy() { - var metadata = new Metadata { + var metadata = new Metadata + { new Metadata.Entry("host", "somehost"), new Metadata.Entry("header2", "header value"), }; diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs index 05e732dbd462b914f90f0228f11e8bf3e46b5880..ea83aaf2c12f7b57e32322dc0cdc8fff5b875cdd 100644 --- a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs +++ b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs @@ -135,7 +135,7 @@ namespace Grpc.IntegrationTesting GrpcEnvironment.Shutdown(); } - private void RunTestCase(string testCase, TestService.ITestServiceClient client) + private void RunTestCase(string testCase, TestService.TestServiceClient client) { switch (testCase) { @@ -163,6 +163,12 @@ namespace Grpc.IntegrationTesting case "compute_engine_creds": RunComputeEngineCreds(client); break; + case "oauth2_auth_token": + RunOAuth2AuthToken(client); + break; + case "per_rpc_creds": + RunPerRpcCreds(client); + break; case "cancel_after_begin": RunCancelAfterBegin(client); break; @@ -355,6 +361,51 @@ namespace Grpc.IntegrationTesting Console.WriteLine("Passed!"); } + public static void RunOAuth2AuthToken(TestService.TestServiceClient client) + { + Console.WriteLine("running oauth2_auth_token"); + var credential = GoogleCredential.GetApplicationDefault().CreateScoped(new[] { AuthScope }); + Assert.IsTrue(credential.RequestAccessTokenAsync(CancellationToken.None).Result); + string oauth2Token = credential.Token.AccessToken; + + // Intercept calls with an OAuth2 token obtained out-of-band. + client.HeaderInterceptor = new MetadataInterceptorDelegate((metadata) => + { + metadata.Add(new Metadata.Entry("Authorization", "Bearer " + oauth2Token)); + }); + + var request = SimpleRequest.CreateBuilder() + .SetFillUsername(true) + .SetFillOauthScope(true) + .Build(); + + var response = client.UnaryCall(request); + + Assert.AreEqual(AuthScopeResponse, response.OauthScope); + Assert.AreEqual(ServiceAccountUser, response.Username); + Console.WriteLine("Passed!"); + } + + public static void RunPerRpcCreds(TestService.TestServiceClient client) + { + Console.WriteLine("running per_rpc_creds"); + + var credential = GoogleCredential.GetApplicationDefault().CreateScoped(new[] { AuthScope }); + Assert.IsTrue(credential.RequestAccessTokenAsync(CancellationToken.None).Result); + string oauth2Token = credential.Token.AccessToken; + + var request = SimpleRequest.CreateBuilder() + .SetFillUsername(true) + .SetFillOauthScope(true) + .Build(); + + var response = client.UnaryCall(request, headers: new Metadata { new Metadata.Entry("Authorization", "Bearer " + oauth2Token) } ); + + Assert.AreEqual(AuthScopeResponse, response.OauthScope); + Assert.AreEqual(ServiceAccountUser, response.Username); + Console.WriteLine("Passed!"); + } + public static void RunCancelAfterBegin(TestService.ITestServiceClient client) { Task.Run(async () =>