Ejemplo n.º 1
0
        public Task <byte[]> SignDataAsync(byte[] data, CancellationToken cancellationToken = default(CancellationToken))
        {
            cancellationToken.ThrowIfCancellationRequested();
            var signature = _credential.CreateSignature(data);

            return(Task.FromResult(Convert.FromBase64String(signature)));
        }
Ejemplo n.º 2
0
        private string GetIDTokenFromServiceAccount(ServiceAccountCredential svc_credential, string target_audience)
        {
            TimeSpan unix_time = (System.DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0));

            long    now    = (long)unix_time.TotalSeconds;
            long    exp    = now + 3600;
            JObject header = new JObject
            {
                ["alg"]  = "RS256",
                ["type"] = "JWT"
            };

            JObject claim = new JObject {
                ["iss"]             = svc_credential.Id,
                ["aud"]             = "https://oauth2.googleapis.com/token",
                ["exp"]             = exp,
                ["iat"]             = now,
                ["target_audience"] = target_audience
            };

            System.Text.UTF8Encoding e  = new System.Text.UTF8Encoding();
            String jwt_header_and_claim = WebEncoders.Base64UrlEncode(e.GetBytes(header.ToString())) + "." + WebEncoders.Base64UrlEncode(e.GetBytes(claim.ToString()));

            var jwt_signature = svc_credential.CreateSignature(System.Text.Encoding.UTF8.GetBytes(jwt_header_and_claim));

            WebClient           client   = new WebClient();
            NameValueCollection formData = new NameValueCollection();

            formData["grant_type"]         = "urn:ietf:params:oauth:grant-type:jwt-bearer";
            formData["assertion"]          = jwt_header_and_claim + "." + jwt_signature;;
            client.Headers["Content-type"] = "application/x-www-form-urlencoded";
            try
            {
                byte[] responseBytes = client.UploadValues("https://oauth2.googleapis.com/token", "POST", formData);
                string Result        = Encoding.UTF8.GetString(responseBytes);

                var assertion_response = JObject.Parse(Result);
                var id_token           = assertion_response["id_token"];

                return(id_token.ToString());
            } catch (WebException ex)
            {
                Stream       receiveStream = ex.Response.GetResponseStream();
                Encoding     encode        = System.Text.Encoding.GetEncoding("utf-8");
                StreamReader readStream    = new StreamReader(receiveStream, encode);
                string       pageContent   = readStream.ReadToEnd();
                Console.WriteLine("Error: " + pageContent);
                throw new System.Exception("Error while getting IDToken " + ex.Message);
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Creates a signed URL which can be used to provide limited access to specific buckets and objects to anyone
        /// in possession of the URL, regardless of whether they have a Google account.
        /// </summary>
        /// <remarks>
        /// <para>
        /// When either of the headers collections are specified, there are certain headers which will be included in the
        /// signed URL's signature, and therefore must be included in requests made with the created URL. These are the
        /// Content-MD5 and Content-Type content headers as well as any content or request header with a name starting
        /// with "x-goog-".
        /// </para>
        /// <para>
        /// If the headers collections are null or empty, no headers are included in the signed URL's signature, so any
        /// requests made with the created URL must not contain Content-MD5, Content-Type, or any header starting with "x-goog-".
        /// </para>
        /// <para>
        /// Note that if the entity is encrypted with customer-supplied encryption keys (see
        /// https://cloud.google.com/storage/docs/encryption for more information), the <b>x-goog-encryption-algorithm</b>,
        /// <b>x-goog-encryption-key</b>, and <b>x-goog-encryption-key-sha256</b> headers will be required when making the
        /// request. However, only the x-goog-encryption-algorithm header is included in the signature for the signed URL.
        /// So the <paramref name="requestHeaders"/> specified only need to have the x-goog-encryption-algorithm header.
        /// The other headers can be included, but will be ignored.
        /// </para>
        /// <para>
        /// Note that when GET is specified as the <paramref name="requestMethod"/> (or it is null, in which case GET is
        /// used), both GET and HEAD requests can be made with the created signed URL.
        /// </para>
        /// <para>
        /// See https://cloud.google.com/storage/docs/access-control/signed-urls for more information on signed URLs.
        /// </para>
        /// </remarks>
        /// <param name="bucket">The name of the bucket. Must not be null.</param>
        /// <param name="objectName">The name of the object within the bucket. May be null, in which case the signed URL
        /// will refer to the bucket instead of an object.</param>
        /// <param name="expiration">The point in time after which the signed URL will be invalid. May be null, in which
        /// case the signed URL never expires.</param>
        /// <param name="requestMethod">The HTTP request method for which the signed URL is allowed to be used. May be null,
        /// in which case GET will be used.</param>
        /// <param name="requestHeaders">The headers which will be included with the request. May be null.</param>
        /// <param name="contentHeaders">The headers for the content which will be included with the request.
        /// May be null.</param>
        /// <returns>
        /// The signed URL which can be used to provide access to a bucket or object for a limited amount of time.
        /// </returns>
        public string Sign(
            string bucket,
            string objectName,
            DateTimeOffset?expiration,
            HttpMethod requestMethod = null,
            Dictionary <string, IEnumerable <string> > requestHeaders = null,
            Dictionary <string, IEnumerable <string> > contentHeaders = null)
        {
            StorageClientImpl.ValidateBucketName(bucket);

            var expiryUnixSeconds = ((int?)((expiration - UnixEpoch)?.TotalSeconds))?.ToString(CultureInfo.InvariantCulture);
            var resourcePath      = $"/{bucket}";

            if (objectName != null)
            {
                resourcePath += $"/{Uri.EscapeDataString(objectName)}";
            }
            var extensionHeaders = GetExtensionHeaders(requestHeaders, contentHeaders);

            var contentMD5  = GetFirstHeaderValue(contentHeaders, "Content-MD5");
            var contentType = GetFirstHeaderValue(contentHeaders, "Content-Type");

            var signatureLines = new List <string>
            {
                (requestMethod ?? HttpMethod.Get).ToString(),
                contentMD5,
                contentType,
                expiryUnixSeconds
            };

            signatureLines.AddRange(extensionHeaders.Select(
                                        header => $"{header.Key}:{string.Join(", ", header.Value)}"));
            signatureLines.Add(resourcePath);

            var signature = _credentials.CreateSignature(Encoding.UTF8.GetBytes(string.Join("\n", signatureLines)));

            var queryParameters = new List <string> {
                $"GoogleAccessId={_credentials.Id}"
            };

            if (expiryUnixSeconds != null)
            {
                queryParameters.Add($"Expires={expiryUnixSeconds}");
            }
            queryParameters.Add($"Signature={WebUtility.UrlEncode(signature)}");
            return($"{StorageHost}{resourcePath}?{string.Join("&", queryParameters)}");
        }