我按照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查询字符串链接可在本页顶部的链接中找到。
此外,我已将查询参数添加为使用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的经验,可以解释我出错的地方?
答案 0 :(得分:0)
我有一个名为aws.signature的软件包,可以为您计算这些签名。而且,我们正在积极开发an S3 client called aws.s3。无论您决定追求自己的客户还是仅使用我们的客户,两者都可能会有所帮助。截至2017年4月,两者都在CRAN上。