AWS S3列表存储桶对象使用查询参数请求身份验证

时间:2015-07-23 06:28:24

标签: r amazon-web-services amazon-s3 httr

我按照AWS S3 API文档中列出的说明使用查询参数对请求进行身份验证:

http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html

下面的代码块将成功返回给定存储桶中所有键的列表。

library(digest)
library(httr)
library(RCurl)

Sys.setenv(TZ="Greenwich")
ts <- strftime(Sys.time(),'%Y%m%dT%H%M%SZ')
d <- strftime(Sys.time(),'%Y%m%d')

bucket <- 'my-bucket'

credentials <- paste(Sys.getenv('AWS_ACCESS_KEY'),d,'us-east-1','s3','aws4_request',sep='/')

request <- paste('GET\n/\nX-Amz-Algorithm=AWS4-HMAC-SHA256',
               '&X-Amz-Credential=',curlEscape(credentials),
               '&X-Amz-Date=',ts,
               '&X-Amz-Expires=60',
               '&X-Amz-SignedHeaders=host\n',
               'host:',bucket,'.s3.amazonaws.com\n\n',
               'host\n',
               'UNSIGNED-PAYLOAD',
               sep='')

request.digest <- digest(request,algo='sha256',serialize=FALSE)
string.to.sign <- paste('AWS4-HMAC-SHA256\n',
                      ts,'\n',
                      d,'/us-east-1/s3/aws4_request\n',
                      request.digest,sep='')

sig <- hmac(paste('AWS4',Sys.getenv('AWS_SECRET_KEY'),sep=''),d,algo='sha256',raw=TRUE)
sig <- hmac(sig,'us-east-1',algo='sha256',raw=TRUE)
sig <- hmac(sig,'s3',algo='sha256',raw=TRUE)
sig <- hmac(sig,'aws4_request',algo='sha256',raw=TRUE)
sig <- hmac(sig,string.to.sign,algo='sha256')

response <- GET(paste('https://',bucket,'.s3.amazonaws.com?',
                    'X-Amz-Algorithm=AWS4-HMAC-SHA256',
                    '&X-Amz-Credential=',curlEscape(credentials),
                    '&X-Amz-Date=',ts,
                    '&X-Amz-Expires=60',
                    '&X-Amz-SignedHeaders=host',
                    '&X-Amz-Signature=',sig,
                    sep=''))

以上工作正常,但我不可能返回位于S3存储桶中的所有密钥。我想添加一个前缀参数只返回匹配的键。但是,当我尝试添加前缀参数以限制请求返回的键结果时,会出现问题。

在文档中,它提供了以下示例GET请求,作为在存储桶中返回更有限的键结果集的方法

GET /?prefix=N&marker=Ned&max-keys=40 HTTP/1.1
Host: quotes.s3.amazonaws.com
Date: Wed, 01 Mar  2006 12:00:00 GMT
Authorization: authorization string

基于此,如果我想添加prefix = m,在我看来我的Canonical URI将是/?prefix=m,我会根据图表将prefix=m添加到我的Canonical查询字符串链接可在本页顶部的链接中找到。

enter image description here

此外,我已将查询参数添加为使用GET()从httr包发送的URL的一部分。

我尝试了几种可能的查询组合,但我不断从服务器获得403响应。以下是根据文档我认为应该工作的示例。

library(digest)
library(httr)
library(RCurl)

Sys.setenv(TZ="Greenwich")
ts <- strftime(Sys.time(),'%Y%m%dT%H%M%SZ')
d <- strftime(Sys.time(),'%Y%m%d')

bucket <- 'my-bucket'

credentials <- paste(Sys.getenv('AWS_ACCESS_KEY'),d,'us-east-1','s3','aws4_request',sep='/')

request <- paste('GET\n/?prefix=m\n',
             'prefix=m',
             '&X-Amz-Algorithm=AWS4-HMAC-SHA256',
             '&X-Amz-Credential=',curlEscape(credentials),
             '&X-Amz-Date=',ts,
             '&X-Amz-Expires=60',
             '&X-Amz-SignedHeaders=host\n',
             'host:',bucket,'.s3.amazonaws.com\n\n',
             'host\n',
             'UNSIGNED-PAYLOAD',
             sep='')

request.digest <- digest(request,algo='sha256',serialize=FALSE)
string.to.sign <- paste('AWS4-HMAC-SHA256\n',
                    ts,'\n',
                    d,'/us-east-1/s3/aws4_request\n',
                    request.digest,sep='')

sig <- hmac(paste('AWS4',Sys.getenv('AWS_SECRET_KEY'),sep=''),d,algo='sha256',raw=TRUE)
sig <- hmac(sig,'us-east-1',algo='sha256',raw=TRUE)
sig <- hmac(sig,'s3',algo='sha256',raw=TRUE)
sig <- hmac(sig,'aws4_request',algo='sha256',raw=TRUE)
sig <- hmac(sig,string.to.sign,algo='sha256')

response <- GET(paste('https://',bucket,'.s3.amazonaws.com?',
                  'prefix=m',
                  '&X-Amz-Algorithm=AWS4-HMAC-SHA256',
                  '&X-Amz-Credential=',curlEscape(credentials),
                  '&X-Amz-Date=',ts,
                  '&X-Amz-Expires=60',
                  '&X-Amz-SignedHeaders=host',
                  '&X-Amz-Signature=',sig,
                  sep=''))

运行上面的代码后,我仍然从服务器收到此消息:

<Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>

有没有人有使用S3 API和R的经验,可以解释我出错的地方?

1 个答案:

答案 0 :(得分:0)

我有一个名为aws.signature的软件包,可以为您计算这些签名。而且,我们正在积极开发an S3 client called aws.s3。无论您决定追求自己的客户还是仅使用我们的客户,两者都可能会有所帮助。截至2017年4月,两者都在CRAN上。