2013-01-10 71 views
3

当我使用我的硬编码访问密钥和密钥时,我能够生成经过身份验证的URL,供用户在S3上查看私人文件。这是用下面的代码完成:如何使用IAM角色生成已验证的S3网址?

import hmac 
import sha 
import urllib 
import time 

filename = "".join([s3_url_prefix, filename]) 
expiry = str(int(time.time()) + 3600) 
h = hmac.new(
    current_app.config.get("S3_SECRET_KEY", None), 
    "".join(["GET\n\n\n", expiry, "\n", filename]), 
    sha 
) 
signature = urllib.quote_plus(base64.encodestring(h.digest()).strip()) 
return "".join([ 
    "https://s3.amazonaws.com", 
    filename, 
    "?AWSAccessKeyId=", 
    current_app.config.get("S3_ACCESS_KEY", None), 
    "&Expires=", 
    expiry, 
    "&Signature=", 
    signature 
]) 

这给了我一些的https://s3.amazonaws.com/bucket_name/path_to_file?AWSAccessKeyId=xxxxx&Expires=5555555555&Signature=eBFeN32eBb2MwxKk4nhGR1UPhk%3D效果。不幸的是,出于安全原因,我无法将密钥存储在配置文件中。为此,我切换到IAM角色。现在,我使用我的密钥:

_iam = boto.connect_iam() 

S3_ACCESS_KEY = _iam.access_key 
S3_SECRET_KEY = _iam.secret_key 

但是,这给了我错误“您提供的AWS访问密钥ID在我们的记录中不存在”。从我的研究中,我明白这是因为我的IAM密钥不是实际的密钥,而是与令牌一起使用。因此,我的问题是双重的:

  1. 如何以编程方式获取令牌?似乎并没有我可以使用的简单IAM属性。

  2. 如何在签名中发送令牌?我相信我的签名最终应该看起来像“”.join([“GET \ n \ n \ n”,过期,“\ n”,令牌,文件名]),但是我找不出要使用的格式。

任何帮助将不胜感激。

回答

5

https://github.com/boto/boto/commit/99e14f3df039997f54a5377cb6aecc83f22c2670(2012年6月)中的generate_url方法进行了更改,可以使用会话凭据对URL进行签名。这意味着你需要使用博托版本2.6.0或更高版本。如果你是,你应该可以这样做:

import boto 
s3 = boto.connect_s3() 
url = s3.generate_url(expires_in=3600, method='GET', bucket='<bucket_name>', key='<key_name>') 

你使用的是什么版本?

+1

谢谢,那肯定做到了。我读过的所有表格都表示无效,但它们已过时。对于任何有兴趣的人,您仍然可以使用上述方法完成此项工作,并将查询字符串中的标记添加为“x-amz-security-token”。 – jmulmer