/// <summary> /// Create a signed URL allowing access to a resource that would /// usually require authentication. /// </summary> /// <remarks> /// <para> /// When using query string authentication you create a query, /// specify an expiration time for the query, sign it with your /// signature, place the data in an HTTP request, and distribute /// the request to a user or embed the request in a web page. /// </para> /// <para> /// A PreSigned URL can be generated for GET, PUT, DELETE and HEAD /// operations on your bucketName, keys, and versions. /// </para> /// </remarks> /// <param name="request">The GetPreSignedUrlRequest that defines the /// parameters of the operation.</param> /// <returns>A string that is the signed http request.</returns> /// <exception cref="T:System.ArgumentException" /> /// <exception cref="T:System.ArgumentNullException" /> public string GetPreSignedURL(GetPreSignedUrlRequest request) { if (Credentials == null) throw new AmazonS3Exception("Credentials must be specified, cannot call method anonymously"); if (request == null) throw new ArgumentNullException("request", "The PreSignedUrlRequest specified is null!"); if (!request.IsSetExpires()) throw new InvalidOperationException("The Expires specified is null!"); var aws4Signing = AWSConfigs.S3Config.UseSignatureVersion4; var region = AWS4Signer.DetermineSigningRegion(Config, "s3", alternateEndpoint: null, request: null); if (aws4Signing && string.IsNullOrEmpty(region)) throw new InvalidOperationException("To use AWS4 signing, a region must be specified in the client configuration using the AuthenticationRegion or Region properties, or be determinable from the service URL."); RegionEndpoint endpoint = RegionEndpoint.GetBySystemName(region); if (endpoint.GetEndpointForService("s3").SignatureVersionOverride == "4") aws4Signing = true; var immutableCredentials = Credentials.GetCredentials(); var irequest = Marshall(request, immutableCredentials.AccessKey, immutableCredentials.Token, aws4Signing); irequest.Endpoint = EndpointResolver.DetermineEndpoint(this.Config, irequest); var context = new Amazon.Runtime.Internal.ExecutionContext(new Amazon.Runtime.Internal.RequestContext(true) { Request = irequest, ClientConfig = this.Config }, null); AmazonS3PostMarshallHandler handler = new AmazonS3PostMarshallHandler(); handler.ProcessRequestHandlers(context); var metrics = new RequestMetrics(); string authorization; if (aws4Signing) { var aws4Signer = new AWS4PreSignedUrlSigner(); var signingResult = aws4Signer.SignRequest(irequest, this.Config, metrics, immutableCredentials.AccessKey, immutableCredentials.SecretKey); authorization = "&" + signingResult.ForQueryParameters; } else { this.Signer.Sign(irequest, this.Config, metrics, immutableCredentials.AccessKey, immutableCredentials.SecretKey); authorization = irequest.Headers[HeaderKeys.AuthorizationHeader]; authorization = authorization.Substring(authorization.IndexOf(":", StringComparison.Ordinal) + 1); authorization = "&Signature=" + AmazonS3Util.UrlEncode(authorization, false); } Uri url = AmazonServiceClient.ComposeUrl(irequest); string result = url.AbsoluteUri + authorization; Protocol protocol = DetermineProtocol(); if (request.Protocol != protocol) { switch (protocol) { case Protocol.HTTP: result = result.Replace("http://", "https://"); break; case Protocol.HTTPS: result = result.Replace("https://", "http://"); break; } } return result; }