【发布时间】:2017-04-29 20:15:30
【问题描述】:
我正在按照 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
基于此,如果我想添加前缀 = m,在我看来我的规范 URI 将是 /?prefix=m,我会根据下面的图表链接将 prefix=m 添加到我的规范查询字符串中在本页顶部的链接中找到。
此外,我已将查询参数添加为使用 httr 包中的 GET() 发送的 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>
有没有人有使用带有 R 的 S3 API 的经验,可以阐明我哪里出错了?
【问题讨论】:
标签: r amazon-web-services amazon-s3 httr