/// <summary>
        /// Creates a JWT access token than can be used in request headers instead of an OAuth2 token.
        /// This is achieved by signing a special JWT using this service account's private key.
        /// <param name="authUri">The URI for which the access token will be valid.</param>
        /// <param name="issueUtc">The issue time of the JWT.</param>
        /// <param name="expiryUtc">The expiry time of the JWT.</param>
        /// </summary>
        private string CreateJwtAccessToken(string authUri, DateTime issueUtc, DateTime expiryUtc)
        {
            JsonWebSignature.Payload payload;

            if (HasExplicitScopes)
            {
                payload = new GoogleJsonWebSignature.Payload()
                {
                    Scope = string.Join(" ", Scopes)
                };
            }
            else
            {
                payload = new JsonWebSignature.Payload()
                {
                    Audience = authUri
                };
            }

            payload.Issuer                = Id;
            payload.Subject               = Id;
            payload.IssuedAtTimeSeconds   = (long)(issueUtc - UnixEpoch).TotalSeconds;
            payload.ExpirationTimeSeconds = (long)(expiryUtc - UnixEpoch).TotalSeconds;

            return(CreateAssertionFromPayload(payload));
        }
        /// <summary>
        /// Creates a JWT access token than can be used in request headers instead of an OAuth2 token.
        /// This is achieved by signing a special JWT using this service account's private key.
        /// <param name="authUri">The URI for which the access token will be valid.</param>
        /// <param name="issueUtc">The issue time of the JWT.</param>
        /// <param name="expiryUtc">The expiry time of the JWT.</param>
        /// </summary>
        private string CreateJwtAccessToken(string authUri, DateTime issueUtc, DateTime expiryUtc)
        {
            var payload = new JsonWebSignature.Payload()
            {
                Issuer                = Id,
                Subject               = Id,
                Audience              = authUri,
                IssuedAtTimeSeconds   = (long)(issueUtc - UnixEpoch).TotalSeconds,
                ExpirationTimeSeconds = (long)(expiryUtc - UnixEpoch).TotalSeconds,
            };

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

            return(CreateAssertionFromPayload(payload));
        }
Пример #4
0
        /// <summary>
        /// Creates a JWT access token than can be used in request headers instead of an OAuth2 token.
        /// This is achieved by signing a special JWT using this service account's private key.
        /// <param name="authUri">The URI for which the access token will be valid.</param>
        /// </summary>
        private string CreateJwtAccessToken(string authUri)
        {
            var issuedDateTime = Clock.UtcNow;
            var issued         = (int)(issuedDateTime - UnixEpoch).TotalSeconds;
            var payload        = new JsonWebSignature.Payload()
            {
                Issuer                = Id,
                Subject               = Id,
                Audience              = authUri,
                IssuedAtTimeSeconds   = issued,
                ExpirationTimeSeconds = issued + 3600,
            };

            return(CreateAssertionFromPayload(payload));
        }
        /// <summary>
        /// Signs JWT token using the private key and returns the serialized assertion.
        /// </summary>
        /// <param name="payload">the JWT payload to sign.</param>
        private string CreateAssertionFromPayload(JsonWebSignature.Payload payload)
        {
            string serializedHeader  = CreateSerializedHeader();
            string serializedPayload = NewtonsoftJsonSerializer.Instance.Serialize(payload);

            var assertion = new StringBuilder();

            assertion.Append(TokenEncodingHelpers.UrlSafeBase64Encode(serializedHeader))
            .Append('.')
            .Append(TokenEncodingHelpers.UrlSafeBase64Encode(serializedPayload));
            var signature = CreateSignature(Encoding.ASCII.GetBytes(assertion.ToString()));

            assertion.Append('.').Append(TokenEncodingHelpers.UrlSafeEncode(signature));
            return(assertion.ToString());
        }
Пример #6
0
        /// <summary>
        /// Signs JWT token using the private key and returns the serialized assertion.
        /// </summary>
        /// <param name="payload">the JWT payload to sign.</param>
        private string CreateAssertionFromPayload(JsonWebSignature.Payload payload)
        {
            string serializedHeader  = CreateSerializedHeader();
            string serializedPayload = NewtonsoftJsonSerializer.Instance.Serialize(payload);

            StringBuilder assertion = new StringBuilder();

            assertion.Append(UrlSafeBase64Encode(serializedHeader))
            .Append(".")
            .Append(UrlSafeBase64Encode(serializedPayload));

            // Sign the header and the payload.
            var hashAlg = new SHA256CryptoServiceProvider();

            byte[] assertionHash = hashAlg.ComputeHash(Encoding.ASCII.GetBytes(assertion.ToString()));

            var signature = UrlSafeBase64Encode(key.SignHash(assertionHash, "2.16.840.1.101.3.4.2.1" /* SHA256 OIG */));

            assertion.Append(".").Append(signature);
            return(assertion.ToString());
        }
        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);
        }
        /// <summary>
        /// Signs JWT token using the private key and returns the serialized assertion.
        /// </summary>
        /// <param name="payload">the JWT payload to sign.</param>
        private string CreateAssertionFromPayload(JsonWebSignature.Payload payload)
        {
            string serializedHeader  = CreateSerializedHeader();
            string serializedPayload = NewtonsoftJsonSerializer.Instance.Serialize(payload);

            StringBuilder assertion = new StringBuilder();

            assertion.Append(UrlSafeBase64Encode(serializedHeader))
            .Append(".")
            .Append(UrlSafeBase64Encode(serializedPayload));

            // Sign the header and the payload.
            var hashAlg = SHA256.Create();

            byte[] assertionHash = hashAlg.ComputeHash(Encoding.ASCII.GetBytes(assertion.ToString()));
#if NETSTANDARD
            var sigBytes = key.SignHash(assertionHash, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
#else
            var sigBytes = key.SignHash(assertionHash, Sha256Oig);
#endif
            var signature = UrlSafeBase64Encode(sigBytes);
            assertion.Append(".").Append(signature);
            return(assertion.ToString());
        }
		/// <summary>
		/// Creates a JWT access token than can be used in request headers instead of an OAuth2 token.
		/// This is achieved by signing a special JWT using this service account's private key.
		/// <param name="authUri">The URI for which the access token will be valid.</param>
		/// </summary>
		private string CreateJwtAccessToken(string authUri)
		{
			var issuedDateTime = Clock.UtcNow;
			var issued = (int)(issuedDateTime - UnixEpoch).TotalSeconds;
			var payload = new JsonWebSignature.Payload()
			{
				Issuer = Id,
				Subject = Id,
				Audience = authUri,
				IssuedAtTimeSeconds = issued,
				ExpirationTimeSeconds = issued + 3600,
			};

			return CreateAssertionFromPayload(payload);
		}