public Task <byte[]> SignDataAsync(byte[] data, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); var signature = _credential.CreateSignature(data); return(Task.FromResult(Convert.FromBase64String(signature))); }
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); } }
/// <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)}"); }