Example #1
0
        public async Task FetchesOidcToken()
        {
            // A little bit after the tokens returned from OidcTokenFakes were issued.
            var clock          = new MockClock(new DateTime(2020, 5, 13, 15, 0, 0, 0, DateTimeKind.Utc));
            var messageHandler = new OidcTokenResponseSuccessMessageHandler();
            var initializer    = new ServiceAccountCredential.Initializer("MyId", "http://will.be.ignored")
            {
                Clock             = clock,
                ProjectId         = "a_project_id",
                HttpClientFactory = new MockHttpClientFactory(messageHandler)
            };
            var credential = new ServiceAccountCredential(initializer.FromPrivateKey(PrivateKey));

            // The fake Oidc server returns valid tokens (expired in the real world for safety)
            // 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 some but not enough that the token expires.
            clock.UtcNow = clock.UtcNow.AddMinutes(20);
            signedToken  = SignedToken <Header, Payload> .FromSignedToken(await oidcToken.GetAccessTokenAsync());

            Assert.Equal("https://first_call.test", signedToken.Payload.Audience);
            // Only the first call should have resulted in a request. The second time the token hadn't expired.
            Assert.Equal(1, messageHandler.Calls);
        }
 public void WithInvalidTokenFormat()
 {
     Assert.Throws <ArgumentException>(
         () => OidcTokenOptions
         .FromTargetAudience("dummy_target_audience")
         .WithTokenFormat((OidcTokenFormat)5));
 }
Example #3
0
        public async Task RefreshesOidcToken()
        {
            // A little bit after the tokens returned from OidcTokenFakes were issued.
            var clock          = new MockClock(new DateTime(2020, 5, 13, 15, 0, 0, 0, DateTimeKind.Utc));
            var messageHandler = new OidcTokenResponseSuccessMessageHandler();
            var initializer    = new ServiceAccountCredential.Initializer("MyId", "http://will.be.ignored")
            {
                Clock             = clock,
                ProjectId         = "a_project_id",
                HttpClientFactory = new MockHttpClientFactory(messageHandler)
            };
            var credential = new ServiceAccountCredential(initializer.FromPrivateKey(PrivateKey));

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

            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 void FromTargetAudience()
        {
            var options = OidcTokenOptions.FromTargetAudience("dummy_target_audience");

            Assert.Equal("dummy_target_audience", options.TargetAudience);
            Assert.Equal(OidcTokenFormat.Full, options.TokenFormat);
        }
Example #5
0
        /// <summary>
        /// Authenticates using the client id and credentials, then fetches
        /// the uri.
        /// </summary>
        /// <param name="iapClientId">The client id observed on
        /// https://console.cloud.google.com/apis/credentials. </param>
        /// <param name="credentialsFilePath">Path to the credentials .json file
        /// downloaded from https://console.cloud.google.com/apis/credentials.
        /// </param>
        /// <param name="uri">HTTP uri to fetch.</param>
        /// <returns>The http response body as a string.</returns>
        public async Task <string> InvokeRequestAsync(string iapClientId, string credentialsFilePath, string uri)
        {
            // Read credentials from the credentials .json file.
            ServiceAccountCredential saCredential;

            using (var fs = new FileStream(credentialsFilePath, FileMode.Open, FileAccess.Read))
            {
                saCredential = ServiceAccountCredential.FromServiceAccountData(fs);
            }

            // Request an OIDC token for the Cloud IAP-secured client ID.
            OidcToken oidcToken = await saCredential.GetOidcTokenAsync(OidcTokenOptions.FromTargetAudience(iapClientId)).ConfigureAwait(false);

            // Always request the string token from the OIDC token, the OIDC token will refresh the string token if it expires.
            string token = await oidcToken.GetAccessTokenAsync().ConfigureAwait(false);

            // Include the OIDC token in an Authorization: Bearer header to
            // IAP-secured resource
            using (var httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
                string response = await httpClient.GetStringAsync(uri).ConfigureAwait(false);

                return(response);
            }
        }
        public async Task OidcTokenProvider_ComputeCredential()
        {
            // This test only executes on GCE so we are certain to have a ComputeCredential.
            GoogleCredential credential = GoogleCredential.FromComputeCredential();

            OidcToken token = await credential.GetOidcTokenAsync(
                OidcTokenOptions.FromTargetAudience("https://this.is.a.test"));

            // Check an access token (really id_token) is available.
            Assert.NotNull(await token.GetAccessTokenAsync());
            // If IdToken is set and AccessToken is not, AccessToken is set to
            // IdToken, so we can always check here that AccessToken is not null.
            Assert.NotNull(token.TokenResponse.AccessToken);
            // The enpoint does not send an expiry, bu we set it to the id_token
            // expiry.
            Assert.NotNull(token.TokenResponse.ExpiresInSeconds);

            var verificationOptions = new SignedTokenVerificationOptions();

            verificationOptions.TrustedAudiences.Add("https://this.is.a.test");

            var payload = await JsonWebSignature.VerifySignedTokenAsync(await token.GetAccessTokenAsync(), verificationOptions);

            Assert.NotNull(payload);
            Assert.Contains("https://this.is.a.test", payload.AudienceAsList);
        }
 public async Task FromUserCredential_OidcTokenFails()
 {
     var stream     = new MemoryStream(Encoding.UTF8.GetBytes(DummyUserCredentialFileContents));
     var credential = GoogleCredential.FromStream(stream);
     await Assert.ThrowsAsync <InvalidOperationException>(
         () => credential.GetOidcTokenAsync(OidcTokenOptions.FromTargetAudience("audience")));
 }
        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);
        }
Example #9
0
        protected override CredentialsRefreshState GenerateNewCredentials()
        {
            var configuredRegion = AWSConfigs.AWSRegion;
            var region           = string.IsNullOrEmpty(configuredRegion) ? DefaultSTSClientRegion : RegionEndpoint.GetBySystemName(configuredRegion);

            Amazon.SecurityToken.Model.Credentials cc = null;
            try
            {
                var stsConfig = ServiceClientHelpers.CreateServiceConfig(ServiceClientHelpers.STS_ASSEMBLY_NAME, ServiceClientHelpers.STS_SERVICE_CONFIG_NAME);
                stsConfig.RegionEndpoint = region;

                var stsClient = new AmazonSecurityTokenServiceClient(new AnonymousAWSCredentials());

                OidcToken oidcToken = SourceCredentials.GetOidcTokenAsync(OidcTokenOptions.FromTargetAudience(TargetAudience).WithTokenFormat(OidcTokenFormat.Standard)).Result;

                TargetAssumeRoleRequest.WebIdentityToken = oidcToken.GetAccessTokenAsync().Result;

                AssumeRoleWithWebIdentityResponse sessionTokenResponse = stsClient.AssumeRoleWithWebIdentityAsync(TargetAssumeRoleRequest).Result;

                cc = sessionTokenResponse.Credentials;
                _logger.InfoFormat("New credentials created for assume role that expire at {0}", cc.Expiration.ToString("yyyy-MM-ddTHH:mm:ss.fffffffK", CultureInfo.InvariantCulture));
                return(new CredentialsRefreshState(new ImmutableCredentials(cc.AccessKeyId, cc.SecretAccessKey, cc.SessionToken), cc.Expiration));
            }
            catch (Exception e)
            {
                var msg       = "Error exchanging Google OIDC token for AWS STS ";
                var exception = new InvalidOperationException(msg, e);
                Logger.GetLogger(typeof(GoogleCompatCredentials)).Error(exception, exception.Message);
                throw exception;
            }
        }
    /// <summary>
    /// Obtains an OIDC token for authentication an IAP request.
    /// </summary>
    /// <param name="iapClientId">The client ID observed on
    /// https://console.cloud.google.com/apis/credentials. </param>
    /// <param name="cancellationToken">The token to propagate operation cancel notifications.</param>
    /// <returns>The HTTP response message.</returns>
    public async Task <OidcToken> GetOidcTokenAsync(string iapClientId, CancellationToken cancellationToken)
    {
        // Obtain the application default credentials.
        GoogleCredential credential = await GoogleCredential.GetApplicationDefaultAsync(cancellationToken);

        // Request an OIDC token for the Cloud IAP-secured client ID.
        return(await credential.GetOidcTokenAsync(OidcTokenOptions.FromTargetAudience(iapClientId), cancellationToken));
    }
Example #11
0
        public async Task GetOidcTokenAsync_Failure()
        {
            var credential = CreateImpersonatedCredentialWithErrorResponse();
            var oidcToken  = await credential.GetOidcTokenAsync(OidcTokenOptions.FromTargetAudience("will.be.ignored"));

            var ex = await Assert.ThrowsAsync <TokenResponseException>(() => oidcToken.GetAccessTokenAsync());

            Assert.Equal(ErrorResponseContent, ex.Error.Error);
        }
Example #12
0
        public async Task GetOidcTokenAsync()
        {
            var credential = CreateImpersonatedCredentialWithIdTokenResponse();
            var oidcToken  = await credential.GetOidcTokenAsync(OidcTokenOptions.FromTargetAudience("will.be.ignored"));

            var token = await oidcToken.GetAccessTokenAsync();

            Assert.Equal(674146, oidcToken.TokenResponse.ExpiresInSeconds);
            Assert.Equal(OidcComputeSuccessMessageHandler.FirstCallToken, token);
        }
Example #13
0
    /// <summary>
    /// Obtains an OIDC token for authentication an IAP request.
    /// </summary>
    /// <param name="iapClientId">The client ID observed on
    /// https://console.cloud.google.com/apis/credentials. </param>
    /// <param name="credentialsFilePath">Path to the credentials .json file
    /// downloaded from https://console.cloud.google.com/apis/credentials.
    /// </param>
    /// <param name="cancellationToken">The token to propagate operation cancel notifications.</param>
    /// <returns>The HTTP response message.</returns>
    public async Task <OidcToken> GetOidcTokenAsync(string iapClientId, string credentialsFilePath, CancellationToken cancellationToken)
    {
        // Read credentials from the credentials .json file.
        GoogleCredential credential = await GoogleCredential
                                      .FromFileAsync(credentialsFilePath, cancellationToken).ConfigureAwait(false);

        // Request an OIDC token for the Cloud IAP-secured client ID.
        return(await credential
               .GetOidcTokenAsync(OidcTokenOptions.FromTargetAudience(iapClientId), cancellationToken).ConfigureAwait(false));
    }
        /// <inheritdoc/>
        public Task <OidcToken> GetOidcTokenAsync(OidcTokenOptions options, CancellationToken cancellationToken = default)
        {
            options.ThrowIfNull(nameof(options));
            // If at some point some properties are added to OidcToken that depend on the token having been fetched
            // then initialize the token here.
            TokenRefreshManager tokenRefreshManager = null;

            tokenRefreshManager = new TokenRefreshManager(
                ct => RefreshOidcTokenAsync(tokenRefreshManager, options, ct), Clock, Logger);
            var oidcToken = (OidcToken)Activator.CreateInstance(typeof(OidcToken), BindingFlags.NonPublic, null, new object[] { tokenRefreshManager }, CultureInfo.InvariantCulture);

            return(Task.FromResult(oidcToken));
        }
        private string CreateJwtAccessTokenForOidc(OidcTokenOptions options, DateTime issueUtc, DateTime expiryUtc)
        {
            var payload = new JsonWebSignature.Payload
            {
                Issuer                = Id,
                Subject               = Id,
                Audience              = EnfonicaAuthConsts.OidcTokenUrl,
                IssuedAtTimeSeconds   = (long)(issueUtc - UnixEpoch).TotalSeconds,
                ExpirationTimeSeconds = (long)(expiryUtc - UnixEpoch).TotalSeconds,
                TargetAudience        = options.TargetAudience
            };

            return(CreateAssertionFromPayload(payload));
        }
        public void WithTokenFormat()
        {
            var options = OidcTokenOptions
                          .FromTargetAudience("dummy_target_audience")
                          .WithTokenFormat(OidcTokenFormat.Standard);

            var newOptions = options.WithTokenFormat(OidcTokenFormat.FullWithLicences);

            Assert.NotSame(options, newOptions);
            // Original unchanged.
            Assert.Equal("dummy_target_audience", options.TargetAudience);
            Assert.Equal(OidcTokenFormat.Standard, options.TokenFormat);
            // New only changes token format.
            Assert.Equal("dummy_target_audience", newOptions.TargetAudience);
            Assert.Equal(OidcTokenFormat.FullWithLicences, newOptions.TokenFormat);
        }
        private async Task <bool> RefreshOidcTokenAsync(TokenRefreshManager caller, OidcTokenOptions options, CancellationToken cancellationToken)
        {
            var    now        = Clock.UtcNow;
            var    jwtExpiry  = now + JwtLifetime;
            string jwtForOidc = CreateJwtAccessTokenForOidc(options, now, jwtExpiry);

            var req = new GoogleAssertionTokenRequest()
            {
                Assertion = jwtForOidc
            };

            caller.Token = await req
                           .ExecuteAsync(HttpClient, TokenServerUrl, cancellationToken, Clock, Logger)
                           .ConfigureAwait(false);

            return(true);
        }
Example #18
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());
        }
Example #19
0
        public static async Task <OidcToken> getGoogleOIDCToken(string targetAudience, string credentialsFilePath)
        {
            //GoogleCredential gCredential;
            ServiceAccountCredential saCredential;

            //ComputeCredential cCredential;

            using (var fs = new FileStream(credentialsFilePath, FileMode.Open, FileAccess.Read))
            {
                saCredential = ServiceAccountCredential.FromServiceAccountData(fs);
            }

            //cCredential = new ComputeCredential();
            //gCredential = await GoogleCredential.GetApplicationDefaultAsync();
            OidcToken oidcToken = await saCredential.GetOidcTokenAsync(OidcTokenOptions.FromTargetAudience(targetAudience).WithTokenFormat(OidcTokenFormat.Standard)).ConfigureAwait(false);

            return(oidcToken);
        }
        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);
        }
        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);
        }
Example #22
0
        public async Task FromServiceAccountCredential_FetchesOicdToken()
        {
            var clock = new MockClock {
                UtcNow = new DateTime(2020, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)
            };
            var messageHandler = new OidcTokenSuccessMessageHandler(clock);
            var initializer    = new ServiceAccountCredential.Initializer("MyId", "http://will.be.ignored")
            {
                Clock             = clock,
                ProjectId         = "a_project_id",
                HttpClientFactory = new MockHttpClientFactory(messageHandler)
            };
            var serviceAccountCredential = new ServiceAccountCredential(initializer.FromPrivateKey(ServiceAccountCredentialTests.PrivateKey));
            var googleCredential         = GoogleCredential.FromServiceAccountCredential(serviceAccountCredential);

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

            Assert.Equal("very_fake_access_token_1", await oidcToken.GetAccessTokenAsync());
        }
        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);
        }
Example #24
0
        public async Task <string> Run(string targetAudience, string credentialsFilePath, string uri)
        {
            ServiceAccountCredential saCredential;

            using (var fs = new FileStream(credentialsFilePath, FileMode.Open, FileAccess.Read))
            {
                saCredential = ServiceAccountCredential.FromServiceAccountData(fs);
            }
            OidcToken oidcToken = await saCredential.GetOidcTokenAsync(OidcTokenOptions.FromTargetAudience(targetAudience).WithTokenFormat(OidcTokenFormat.Standard)).ConfigureAwait(false);

            string token = await oidcToken.GetAccessTokenAsync().ConfigureAwait(false);

            using (var httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
                string response = await httpClient.GetStringAsync(uri).ConfigureAwait(false);

                Console.WriteLine(response);
                return(response);
            }
        }
        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 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);
        }
Example #27
0
        public async Task <string> Run(string targetAudience, string credentialsFilePath, string uri)
        {
            ServiceAccountCredential saCredential;

            using (var fs = new FileStream(credentialsFilePath, FileMode.Open, FileAccess.Read))
            {
                saCredential = ServiceAccountCredential.FromServiceAccountData(fs);
            }
            OidcToken oidcToken = await saCredential.GetOidcTokenAsync(OidcTokenOptions.FromTargetAudience(targetAudience).WithTokenFormat(OidcTokenFormat.Standard)).ConfigureAwait(false);

            string token = await oidcToken.GetAccessTokenAsync().ConfigureAwait(false);

            // the following snippet verifies an id token.
            // this step is done on the  receiving end of the oidc endpoint
            // adding this step in here as just as a demo on how to do this
            //var options = SignedTokenVerificationOptions.Default;
            SignedTokenVerificationOptions options = new SignedTokenVerificationOptions
            {
                IssuedAtClockTolerance = TimeSpan.FromMinutes(1),
                ExpiryClockTolerance   = TimeSpan.FromMinutes(1),
                TrustedAudiences       = { targetAudience },
                CertificatesUrl        = "https://www.googleapis.com/oauth2/v3/certs" // default value
            };
            var payload = await JsonWebSignature.VerifySignedTokenAsync(token, options);

            Console.WriteLine("Verified with audience " + payload.Audience);
            // end verification

            // use the token
            using (var httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
                string response = await httpClient.GetStringAsync(uri).ConfigureAwait(false);

                Console.WriteLine(response);
                return(response);
            }
        }
        public async Task FetchesOidcToken_CorrectPayloadSent()
        {
            var clock = new MockClock {
                UtcNow = new DateTime(2020, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)
            };
            var messageHandler = new OidcTokenSuccessMessageHandler(clock);
            var initializer    = new ServiceAccountCredential.Initializer("MyId", "http://will.be.ignored")
            {
                Clock             = clock,
                ProjectId         = "a_project_id",
                HttpClientFactory = new MockHttpClientFactory(messageHandler)
            };
            var credential = new ServiceAccountCredential(initializer.FromPrivateKey(PrivateKey));

            var expectedPayload = new JsonWebSignature.Payload
            {
                Issuer                = "MyId",
                Subject               = "MyId",
                Audience              = GoogleAuthConsts.OidcAuthorizationUrl,
                IssuedAtTimeSeconds   = (long)(clock.UtcNow - UnixEpoch).TotalSeconds,
                ExpirationTimeSeconds = (long)(clock.UtcNow.Add(JwtLifetime) - UnixEpoch).TotalSeconds,
                TargetAudience        = "any_audience"
            };
            var serializedExpectedPayload     = NewtonsoftJsonSerializer.Instance.Serialize(expectedPayload);
            var urlSafeEncodedExpectedPayload = UrlSafeBase64Encode(serializedExpectedPayload);

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

            await oidcToken.GetAccessTokenAsync();

            var requestFormDict = messageHandler.LatestRequestContent.Split('&')
                                  .ToDictionary(entry => entry.Split('=')[0], entry => entry.Split('=')[1]);
            var assertion = requestFormDict["assertion"];
            // Assertion format shoould be headers.payload.signature
            var encodedPayload = assertion.Split('.')[1];

            Assert.Contains(urlSafeEncodedExpectedPayload, encodedPayload);
        }
 public async Task FromAccessToken_OidcTokenFails()
 {
     var credential = GoogleCredential.FromAccessToken("fake_access_token");
     await Assert.ThrowsAsync <InvalidOperationException>(
         () => credential.GetOidcTokenAsync(OidcTokenOptions.FromTargetAudience("audience")));
 }