public async Task RefreshesOidcToken()
        {
            // A little bit after the tokens returned from OidcTokenFakes were issued.
            var clock          = new MockClock(new DateTime(2020, 5, 21, 9, 20, 0, 0, DateTimeKind.Utc));
            var messageHandler = new OidcComputeSuccessMessageHandler();
            var initializer    = new ComputeCredential.Initializer("http://will.be.ignored", "http://will.be.ignored")
            {
                Clock             = clock,
                HttpClientFactory = new MockHttpClientFactory(messageHandler)
            };
            var credential = new ComputeCredential(initializer);

            // The fake Oidc server returns valid tokens (expired in the real world for safty)
            // but with a set audience that lets us know if the token was refreshed or not.
            var oidcToken = await credential.GetOidcTokenAsync(OidcTokenOptions.FromTargetAudience("will.be.ignored"));

            var signedToken = SignedToken <Header, Payload> .FromSignedToken(await oidcToken.GetAccessTokenAsync());

            Assert.Equal("https://first_call.test", signedToken.Payload.Audience);
            // Move the clock so that the token expires.
            clock.UtcNow = clock.UtcNow.AddHours(2);
            signedToken  = SignedToken <Header, Payload> .FromSignedToken(await oidcToken.GetAccessTokenAsync());

            Assert.Equal("https://subsequent_calls.test", signedToken.Payload.Audience);
            // Two calls, because the second time we tried to get the token, the first one had expired.
            Assert.Equal(2, messageHandler.Calls);
        }
 public async Task SignBlobAsync_UnsupportedCredential()
 {
     var initializer       = new ComputeCredential.Initializer("http://will.be.ignored", "http://will.be.ignored");
     var computeCredential = new ComputeCredential(initializer);
     var googleCredential  = GoogleCredential.FromComputeCredential(computeCredential);
     await Assert.ThrowsAsync <InvalidOperationException>(() => googleCredential.SignBlobAsync(Encoding.ASCII.GetBytes("toSign")));
 }
Пример #3
0
        /// <summary>
        /// Adds firebase authentication to the service collection using a compute credential for the key (not recommended)
        /// </summary>
        /// <param name="services">IServiceCollection instance to which you will be adding the auth policy</param>
        /// <param name="computeCredential">The compute credential to use in the returned Google.Apis.Auth.OAuth2.GoogleCredential</param>
        public static void AddFirebaseAdminFromComputeCredential(
            this IServiceCollection services,
            ComputeCredential computeCredential = null)
        {
            AddAuthPolicy(services);

            CreateApp(GoogleCredential.FromComputeCredential(computeCredential));
        }
Пример #4
0
 public OnGceFactAttribute()
 {
     // Ugly, but this is for tests.
     if (!ComputeCredential.IsRunningOnComputeEngine().GetAwaiter().GetResult())
     {
         Skip = "Not running on GCE";
     }
 }
Пример #5
0
        public void WithHttpClientFactory()
        {
            var credential            = new ComputeCredential();
            var factory               = new HttpClientFactory();
            var credentialWithFactory = Assert.IsType <ComputeCredential>(((IGoogleCredential)credential).WithHttpClientFactory(factory));

            Assert.NotSame(credential, credentialWithFactory);
            Assert.NotSame(credential.HttpClient, credentialWithFactory.HttpClient);
            Assert.NotSame(credential.HttpClientFactory, credentialWithFactory.HttpClientFactory);
            Assert.Same(factory, credentialWithFactory.HttpClientFactory);
        }
Пример #6
0
        public async Task Scoped_Initializer_WithCustomTokenUrl(string[] scopes, string customTokenUrl, string expectedTokenUrl)
        {
            var fakeMessageHandler = new FetchesTokenMessageHandler();
            var credential         = new ComputeCredential(new ComputeCredential.Initializer(customTokenUrl)
            {
                Scopes            = scopes,
                HttpClientFactory = new MockHttpClientFactory(fakeMessageHandler)
            });

            AssertScoped(credential, scopes, expectedTokenUrl);
            await AssertUsesScopedUrl(credential, fakeMessageHandler, expectedTokenUrl);
        }
Пример #7
0
        /// <summary>
        /// Will use compute credentials if running on compute engine, otherwise will use environment variables
        /// </summary>
        /// <returns></returns>
        public static async Task <BigtableCredentials> UseApplicationDefaultCredentialsAsync()
        {
            if (await ComputeCredential.IsRunningOnComputeEngine())
            {
                // Hookup .pem file
                SetDefaultSslKeyFilePath();

                // Get credential
                var credentials = new ComputeCredential(new ComputeCredential.Initializer());

                // Return results
                return(new BigtableCredentials(credentials));
            }

            // Use environment
            return(await UseEnvironmentAsync());
        }
        public async Task FetchesOidcToken_WithDefaultOptions()
        {
            // A little bit after the tokens returned from OidcTokenFakes were issued.
            var clock          = new MockClock(new DateTime(2020, 5, 21, 9, 20, 0, 0, DateTimeKind.Utc));
            var messageHandler = new OidcComputeSuccessMessageHandler();
            var initializer    = new ComputeCredential.Initializer("http://will.be.ignored", "http://will.be.ignored")
            {
                Clock             = clock,
                HttpClientFactory = new MockHttpClientFactory(messageHandler)
            };
            var credential = new ComputeCredential(initializer);

            var oidcToken = await credential.GetOidcTokenAsync(OidcTokenOptions.FromTargetAudience("any_audience"));

            await oidcToken.GetAccessTokenAsync();

            Assert.Equal("?audience=any_audience&format=full", messageHandler.LatestRequest.RequestUri.Query);
        }
Пример #9
0
        public async Task FromComputeCredential_FetchesOidcToken()
        {
            var clock = new MockClock {
                UtcNow = new DateTime(2020, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)
            };
            var messageHandler = new OidcTokenSuccessMessageHandler(clock);
            var initializer    = new ComputeCredential.Initializer("http://will.be.ignored", "http://will.be.ignored")
            {
                Clock             = clock,
                HttpClientFactory = new MockHttpClientFactory(messageHandler)
            };
            var computeCredential = new ComputeCredential(initializer);
            var googleCredential  = GoogleCredential.FromComputeCredential(computeCredential);

            var oidcToken = await googleCredential.GetOidcTokenAsync(OidcTokenOptions.FromTargetAudience("audience"));

            Assert.Equal("very_fake_access_token_1", await oidcToken.GetAccessTokenAsync());
        }
        public async Task FetchesOidcToken_WithDefaultOptions()
        {
            var clock = new MockClock {
                UtcNow = new DateTime(2020, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)
            };
            var messageHandler = new OidcTokenSuccessMessageHandler(clock);
            var initializer    = new ComputeCredential.Initializer("http://will.be.ignored", "http://will.be.ignored")
            {
                Clock             = clock,
                HttpClientFactory = new MockHttpClientFactory(messageHandler)
            };
            var credential = new ComputeCredential(initializer);

            var oidcToken = await credential.GetOidcTokenAsync(OidcTokenOptions.FromTargetAudience("any_audience"));

            await oidcToken.GetAccessTokenAsync();

            Assert.Equal("?audience=any_audience&format=full", messageHandler.LatestRequest.RequestUri.Query);
        }
        public async Task FromComputeCredential_FetchesOidcToken()
        {
            // A little bit after the tokens returned from OidcTokenFakes were issued.
            var clock          = new MockClock(new DateTime(2020, 5, 21, 9, 20, 0, 0, DateTimeKind.Utc));
            var messageHandler = new OidcComputeSuccessMessageHandler();
            var initializer    = new ComputeCredential.Initializer("http://will.be.ignored", "http://will.be.ignored")
            {
                Clock             = clock,
                HttpClientFactory = new MockHttpClientFactory(messageHandler)
            };
            var computeCredential = new ComputeCredential(initializer);
            var googleCredential  = GoogleCredential.FromComputeCredential(computeCredential);

            // The fake Oidc server returns valid tokens (expired in the real world for safty)
            // but with a set audience that lets us know if the token was refreshed or not.
            var oidcToken = await googleCredential.GetOidcTokenAsync(OidcTokenOptions.FromTargetAudience("will.be.ignored"));

            var signedToken = SignedToken <Header, Payload> .FromSignedToken(await oidcToken.GetAccessTokenAsync());

            Assert.Equal("https://first_call.test", signedToken.Payload.Audience);
        }
        public async Task RefreshesOidcToken()
        {
            var clock = new MockClock {
                UtcNow = new DateTime(2020, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)
            };
            var messageHandler = new OidcTokenSuccessMessageHandler(clock);
            var initializer    = new ComputeCredential.Initializer("http://will.be.ignored", "http://will.be.ignored")
            {
                Clock             = clock,
                HttpClientFactory = new MockHttpClientFactory(messageHandler)
            };
            var credential = new ComputeCredential(initializer);

            var oidcToken = await credential.GetOidcTokenAsync(OidcTokenOptions.FromTargetAudience("audience"));

            Assert.Equal("very_fake_access_token_1", await oidcToken.GetAccessTokenAsync());
            // Move the clock so that the token expires.
            clock.UtcNow = clock.UtcNow.AddHours(2);
            Assert.Equal("very_fake_access_token_2", await oidcToken.GetAccessTokenAsync());
            // Two calls, because the second time we tried to get the token, the first one had expired.
            Assert.Equal(2, messageHandler.Calls);
        }
        public async Task FetchesOidcToken()
        {
            var clock = new MockClock {
                UtcNow = new DateTime(2020, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)
            };
            var messageHandler = new OidcTokenSuccessMessageHandler(clock);
            var initializer    = new ComputeCredential.Initializer("http://will.be.ignored", "http://will.be.ignored")
            {
                Clock             = clock,
                HttpClientFactory = new MockHttpClientFactory(messageHandler)
            };
            var credential = new ComputeCredential(initializer);

            var oidcToken = await credential.GetOidcTokenAsync(OidcTokenOptions.FromTargetAudience("audience"));

            Assert.Equal("very_fake_access_token_1", await oidcToken.GetAccessTokenAsync());
            // Move the clock some but not enough that the token expires.
            clock.UtcNow = clock.UtcNow.AddMinutes(20);
            Assert.Equal("very_fake_access_token_1", await oidcToken.GetAccessTokenAsync());
            // Only the first call should have resulted in a request. The second time the token hadn't expired.
            Assert.Equal(1, messageHandler.Calls);
        }
        public static async Task <string> DetermineRuntime()
        {
            // Check for environment variables that indicate a specific runtime.
            foreach (var indicator in environmentIndicators)
            {
                if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable(indicator.Key)))
                {
                    return(indicator.Value);
                }
            }

            // Check metadata server, which indicates GCE.
            if (await ComputeCredential.IsRunningOnComputeEngine())
            {
                return("Compute Engine");
            }
            else
            {
                // Metadata server not available, so it's probably not nunning
                // on Google Cloud.
                return(null);
            }
        }
Пример #15
0
 private void AssertScoped(ComputeCredential credential, string[] scopes, string expectedTokenUrl)
 {
     Assert.Collection(credential.Scopes ?? Enumerable.Empty <string>(),
                       (scopes?.Select <string, Action <string> >(expectedScope => actualScope => Assert.Equal(expectedScope, actualScope)) ?? Enumerable.Empty <Action <string> >()).ToArray());
     Assert.Equal(expectedTokenUrl, credential.EffectiveTokenServerUrl);
 }
Пример #16
0
 /// <summary>
 /// Scoped cannot be used
 /// </summary>
 public BigtableCredentials(ComputeCredential computeCredentials)
 {
     _computeCredentials = computeCredentials;
 }
Пример #17
0
 static string ShowRunningOnComputeEngine() =>
 ComputeCredential.IsRunningOnComputeEngine().Result.ToString();
 public void IsRunningOnComputeEngine_ResultIsCached()
 {
     // Two subsequent invocations should return the same task.
     Assert.Same(ComputeCredential.IsRunningOnComputeEngine(),
                 ComputeCredential.IsRunningOnComputeEngine());
 }
Пример #19
0
        /// <summary>Creates a new default credential.</summary>
        private async Task <GoogleCredential> CreateDefaultCredentialAsync()
        {
            // 1. First try the environment variable.
            string credentialPath = GetEnvironmentVariable(CredentialEnvironmentVariable);

            if (!String.IsNullOrWhiteSpace(credentialPath))
            {
                try
                {
                    return(CreateDefaultCredentialFromFile(credentialPath));
                }
                catch (Exception e)
                {
                    // Catching generic exception type because any corrupted file could manifest in different ways
                    // including but not limited to the System, System.IO or from the Newtonsoft.Json namespace.
                    throw new InvalidOperationException(
                              String.Format("Error reading credential file from location {0}: {1}"
                                            + "\nPlease check the value of the Environment Variable {2}",
                                            credentialPath,
                                            e.Message,
                                            CredentialEnvironmentVariable), e);
                }
            }

            // 2. Then try the well known file.
            credentialPath = GetWellKnownCredentialFilePath();
            if (!String.IsNullOrWhiteSpace(credentialPath))
            {
                try
                {
                    return(CreateDefaultCredentialFromFile(credentialPath));
                }
                catch (FileNotFoundException)
                {
                    // File is not present, eat the exception and move on to the next check.
                    Logger.Debug("Well-known credential file {0} not found.", credentialPath);
                }
                catch (DirectoryNotFoundException)
                {
                    // Directory not present, eat the exception and move on to the next check.
                    Logger.Debug("Well-known credential file {0} not found.", credentialPath);
                }
                catch (Exception e)
                {
                    throw new InvalidOperationException(
                              String.Format("Error reading credential file from location {0}: {1}"
                                            + "\nPlease rerun 'gcloud auth login' to regenerate credentials file.",
                                            credentialPath,
                                            e.Message), e);
                }
            }

            // 3. Then try the compute engine.
            Logger.Debug("Checking whether the application is running on ComputeEngine.");
            if (await ComputeCredential.IsRunningOnComputeEngine().ConfigureAwait(false))
            {
                Logger.Debug("ComputeEngine check passed. Using ComputeEngine Credentials.");
                return(new GoogleCredential(new ComputeCredential()));
            }

            // If everything we tried has failed, throw an exception.
            throw new InvalidOperationException(
                      String.Format("The Application Default Credentials are not available. They are available if running"
                                    + " in Google Compute Engine. Otherwise, the environment variable {0} must be defined"
                                    + " pointing to a file defining the credentials. See {1} for more information.",
                                    CredentialEnvironmentVariable,
                                    HelpPermalink));
        }
Пример #20
0
 private async Task AssertUsesScopedUrl(ComputeCredential credential, FetchesTokenMessageHandler fakeMessageHandler, string expectedTokenUrl)
 {
     Assert.NotNull(await credential.GetAccessTokenForRequestAsync());
     Assert.Equal(1, fakeMessageHandler.Calls);
     Assert.Equal(expectedTokenUrl, fakeMessageHandler.Requests.First().RequestUri.AbsoluteUri);
 }