You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
By clicking “Sign up for GitHub”, you agree to our
terms of service
and
privacy statement
. We’ll occasionally send you account related emails.
Already on GitHub?
Sign in
to your account
response-requested
Waiting on additional info and feedback. Will move to "closing-soon" in 7 days.
I'm having the same issue. I understand that this header is not a part of a query string but is used in signature calculation procedure. However, it simply doesn't work.
Here is by pre-signed url request:
GetPreSignedUrlRequest request1 = new GetPreSignedUrlRequest { BucketName = bucketName, Key = objectKey, Verb = HttpVerb.PUT, Expires = DateTime.UtcNow.AddHours(duration), Headers = { ["x-amz-tagging"] = "TagKey=TagValue" } };
and this is my http request configuration:
HttpWebRequest httpRequest = WebRequest.Create(url) as HttpWebRequest; httpRequest.Method = "PUT"; httpRequest.Headers.Add("x-amz-tagging", "TagKey=TagValue");
End result: 403 (Forbidden)
Hi
@AntShep
/
@yyc-github
,
Good afternoon.
While looking closely at the issue and troubleshooting it, it appears that this behavior is as per design.
At high level:
AWS4Signer.CanonicalizeHeaders()
appears to canonicalize the headers with values for the request, with the format
[headername:headervalue]\n
. This also includes
x-amz-tagging
header.
These canonicalized headers are included as part of canonicalized request as per
AWS4Signer.CanonicalizeRequestHelper()
along with header names.
The canonicalized request is used to
ComputeSignature
in
AWS4Signer.SignRequest()
.
The headers are never included as part of query string, but are used to compute signature.
Hence, when user needs to use presigned URL, then the exact value for
x-amz-tagging
also needs to be specified
.
The .NET SDK is using the specification mentioned at
https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
. All the headers are used to calculate the signature, but these are never included as part of query string. The only information in query string for headers is parameter
X-Amz-SignedHeaders
which indicates which headers are included to calculate the signature (
host;x-amz-tagging
in your case).
I'm not sure if including
x-amz-tagging
in query string is a scalable solution. This is because user can specify any number of headers with variable length values and the query string length has a limitation. Also, not sure if including headers in query string would cause any other issues with presigned URLs.
Hope this explains the behavior. Kindly confirm if this issue could be closed.
Thanks,
Ashish
Originally posted by
@ashishdhingra
in
#1696 (comment)
Pre-signed url doesn't work when x-amz-tagging
Pre-signed url doesn't work when 'x-amz-tagging' header is added
Aug 9, 2021
Hi
@vlmironoff
,
Good afternoon.
Unfortunately, I'm unable to reproduce the issue. The following code works like a charm:
using Amazon.S3;
using Amazon.S3.Model;
using System;
using System.IO;
using System.Net;
namespace PreSignedUrl_XAmzTagging_Issue1696
class Program
private static string bucket = "<<bucket_name>>";
private static string key = "<<object_key>>";
private static string filePath = @"<<absolute_file_path>>";
static void Main(string[] args)
var amazonS3Client = new AmazonS3Client();
var request = new GetPreSignedUrlRequest
BucketName = bucket,
Key = key,
Verb = HttpVerb.PUT,
Expires = DateTime.Now.AddMinutes(60),
Headers = { ["x-amz-tagging"] = "TagKey=TagValue" }
var url = amazonS3Client.GetPreSignedURL(request);
UploadFile(filePath, url);
private async static void UploadFile(string filePath, string presignedUrl)
if (string.IsNullOrWhiteSpace(filePath)) throw new ArgumentNullException("filePath");
if (string.IsNullOrWhiteSpace(presignedUrl)) throw new ArgumentNullException("presignedUrl");
if (!File.Exists(filePath)) throw new FileNotFoundException($"File '{filePath}' not found");
byte[] bytes;
await using (var fs = File.Open(filePath, FileMode.Open))
bytes = new BinaryReader(fs).ReadBytes((int)fs.Length);
var httpRequest = WebRequest.Create(presignedUrl) as HttpWebRequest;
if(httpRequest != null)
httpRequest.Method = "PUT";
httpRequest.Headers.Add("x-amz-tagging", "TagKey=TagValue");
httpRequest.ContentLength = bytes.Length;
using (var requestStream = httpRequest.GetRequestStream())
requestStream.Write(bytes, 0, bytes.Length);
var httpResponse = httpRequest.GetResponse() as HttpWebResponse;
Here are the contents of .csproj
file:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AWSSDK.S3" Version="3.7.1.21" />
</ItemGroup>
</Project>
I was able to upload the file using above code. The code above uses default
credentials in my profile chain which has Administrator access (other policy should work as long as it has permissions to upload objects to S3 bucket).
Looks like the credentials you are using does not have access to upload objects to S3 bucket based on 403 (Forbidden)
error. Could you please check your permissions? Also share the log/stack trace.
Thanks,
Ashish
response-requested
Waiting on additional info and feedback. Will move to "closing-soon" in 7 days.
and removed
This issue is a bug.
response-requested
Waiting on additional info and feedback. Will move to "closing-soon" in 7 days.
labels
Aug 9, 2021
response-requested
Waiting on additional info and feedback. Will move to "closing-soon" in 7 days.