public string GenerateV4UploadSignedUrl( string bucketName = "your-unique-bucket-name", string objectName = "your-object-name", string credentialFilePath = "my-local-path/my-credential-file-name") { UrlSigner urlSigner = UrlSigner.FromServiceAccountPath(credentialFilePath); var contentHeaders = new Dictionary <string, IEnumerable <string> > { { "Content-Type", new[] { "text/plain" } } }; // V4 is the default signing version. UrlSigner.Options options = UrlSigner.Options.FromDuration(TimeSpan.FromHours(1)); UrlSigner.RequestTemplate template = UrlSigner.RequestTemplate .FromBucket(bucketName) .WithObjectName(objectName) .WithHttpMethod(HttpMethod.Put) .WithContentHeaders(contentHeaders); string url = urlSigner.Sign(template, options); Console.WriteLine("Generated PUT signed URL:"); Console.WriteLine(url); Console.WriteLine("You can use this URL with any user agent, for example:"); Console.WriteLine($"curl -X PUT -H 'Content-Type: text/plain' --upload-file my-file '{url}'"); return(url); }
public async Task SignedURLPut() { var bucketName = _fixture.BucketName; var credential = (await GoogleCredential.GetApplicationDefaultAsync()).UnderlyingCredential as ServiceAccountCredential; var httpClient = new HttpClient(); // Sample: SignedURLPut // Create a request template that will be used to create the signed URL. var destination = "places/world.txt"; UrlSigner.RequestTemplate requestTemplate = UrlSigner.RequestTemplate .FromBucket(bucketName) .WithObjectName(destination) .WithHttpMethod(HttpMethod.Put) .WithContentHeaders(new Dictionary <string, IEnumerable <string> > { { "Content-Type", new[] { "text/plain" } } }); // Create options specifying for how long the signer URL will be valid. UrlSigner.Options options = UrlSigner.Options.FromDuration(TimeSpan.FromHours(1)); // Create a signed URL which allows the requester to PUT data with the text/plain content-type. UrlSigner urlSigner = UrlSigner.FromServiceAccountCredential(credential); string url = urlSigner.Sign(requestTemplate, options); // Upload the content into the bucket using the signed URL. string source = "world.txt"; ByteArrayContent content; using (FileStream stream = File.OpenRead(source)) { byte[] data = new byte[stream.Length]; stream.Read(data, 0, data.Length); content = new ByteArrayContent(data) { Headers = { ContentType = new MediaTypeHeaderValue("text/plain") } }; } HttpResponseMessage response = await httpClient.PutAsync(url, content); // End sample Assert.True(response.IsSuccessStatusCode); var client = StorageClient.Create(); var result = new MemoryStream(); await client.DownloadObjectAsync(bucketName, destination, result); using (var stream = File.OpenRead(source)) { var data = new byte[stream.Length]; stream.Read(data, 0, data.Length); Assert.Equal(result.ToArray(), data); } await client.DeleteObjectAsync(bucketName, destination); }
public async Task SignedUrlWithIamServiceBlobSigner() { _fixture.SkipIf(Platform.Instance().Type == PlatformType.Unknown); var bucketName = _fixture.BucketName; var objectName = _fixture.HelloStorageObjectName; var credential = (await GoogleCredential.GetApplicationDefaultAsync()).UnderlyingCredential as ServiceAccountCredential; var httpClient = new HttpClient(); // Sample: IamServiceBlobSignerUsage // First obtain the email address of the default service account for this instance from the metadata server. HttpRequestMessage serviceAccountRequest = new HttpRequestMessage { // Note: you could use 169.254.169.254 as the address to avoid a DNS lookup. RequestUri = new Uri("http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/email"), Headers = { { "Metadata-Flavor", "Google" } } }; HttpResponseMessage serviceAccountResponse = await httpClient.SendAsync(serviceAccountRequest).ConfigureAwait(false); serviceAccountResponse.EnsureSuccessStatusCode(); string serviceAccountId = await serviceAccountResponse.Content.ReadAsStringAsync(); // Create an IAM service client object using the default application credentials. GoogleCredential iamCredential = await GoogleCredential.GetApplicationDefaultAsync(); iamCredential = iamCredential.CreateScoped(IamService.Scope.CloudPlatform); IamService iamService = new IamService(new BaseClientService.Initializer { HttpClientInitializer = iamCredential }); // Create a request template that will be used to create the signed URL. UrlSigner.RequestTemplate requestTemplate = UrlSigner.RequestTemplate .FromBucket(bucketName) .WithObjectName(objectName) .WithHttpMethod(HttpMethod.Get); // Create options specifying for how long the signer URL will be valid. UrlSigner.Options options = UrlSigner.Options.FromDuration(TimeSpan.FromHours(1)); // Create a URL signer that will use the IAM service for signing. This signer is thread-safe, // and would typically occur as a dependency, e.g. in an ASP.NET Core controller, where the // same instance can be reused for each request. IamServiceBlobSigner blobSigner = new IamServiceBlobSigner(iamService, serviceAccountId); UrlSigner urlSigner = UrlSigner.FromBlobSigner(blobSigner); // Use the URL signer to sign a request for the test object for the next hour. string url = await urlSigner.SignAsync(requestTemplate, options); // Prove we can fetch the content of the test object with a simple unauthenticated GET request. HttpResponseMessage response = await httpClient.GetAsync(url); string content = await response.Content.ReadAsStringAsync(); // End sample Assert.Equal(_fixture.HelloWorldContent, content); }