Ja͢*_*͢ck 9 php file-upload amazon-s3 amazon-ec2 amazon-web-services
这是我之前关于使用实例配置文件签署策略文档的问题的后续行动.
我正在开发一个允许拖放上传到S3存储桶的系统; 首先向包含文件元数据的服务器发出AJAX请求.验证后,我的服务器会使用用于完成上传的表单参数进行响应.
设置基于浏览器的上传的过程在这里得到了很好的解释,它在我的本地测试环境中按预期工作.
但是,一旦我的应用程序部署在EC2实例上,我在浏览器尝试上传文件时就会看到此错误:
<Error>
<Code>InvalidAccessKeyId</Code>
<Message>The AWS Access Key Id you provided does not exist in our records.</Message>
<RequestId>...</RequestId>
<HostId>...</HostId>
<AWSAccessKeyId>ASIAxxxyyyzzz</AWSAccessKeyId>
</Error>
Run Code Online (Sandbox Code Playgroud)
ASIAxxxyyyzzz
这里的值来自实例角色凭证,从元数据服务获得; 似乎这些凭据不能在EC2之外使用,以方便基于浏览器的上传.
我也看了安全令牌服务,通过这样做生成另一组临时凭证:
$token = $sts->assumeRole(array(
'RoleArn' => 'arn:aws:iam::xyz:role/mydomain.com',
'RoleSessionName' => 'uploader',
));
$credentials = new Credentials($token['Credentials']['AccessKeyId'], $token['Credentials']['SecretAccessKey']);
Run Code Online (Sandbox Code Playgroud)
该调用为我提供了一组新的凭据,但在使用它时它会产生与上述相同的错误.
我希望有人之前已经这样做了,可以告诉我我错过了什么愚蠢的东西:)
正如dcro 的回答所指出的,当您使用临时凭据时,需要将会话令牌传递给您正在使用的服务。官方文档提到了该x-amz-security-token
字段,但似乎表明它仅用于 DevPay;这可能是因为 DevPay 使用相同类型的临时凭证,因此需要会话安全令牌。
2013-10-16:亚马逊更新了他们的文档以使这一点更加明显。
事实证明,甚至根本不需要使用 STS;元数据服务接收到的凭证也带有这样的会话令牌。当 SDK 与临时凭证一起使用时,会自动为您传递此令牌,但在这种情况下,最终请求是由浏览器发出的,因此需要显式传递。
以下是我的工作代码:
$credentials = Credentials::factory();
$signer = new S3Signature();
$policy = new AwsUploadPolicy(new DateTime('+1 hour', new DateTimeZone('UTC')));
$policy->setBucket('upload.mydomain.com');
$policy->setACL($policy::ACL_PUBLIC_READ);
$policy->setKey('uploads/test.jpg');
$policy->setContentType('image/jpeg');
$policy->setContentLength(5034);
$fields = array(
'AWSAccessKeyId' => $credentials->getAccessKeyId(),
'key' => $path,
'Content-Type' => $type,
'acl' => $policy::ACL_PUBLIC_READ,
'policy' => $policy,
);
if ($credentials->getSecurityToken()) {
// pass security token
$fields['x-amz-security-token'] = $credentials->getSecurityToken();
$policy->setSecurityToken($credentials->getSecurityToken());
}
$fields['signature'] = $signer->signString($policy, $credentials);
Run Code Online (Sandbox Code Playgroud)
我正在使用一个辅助类来构建策略,称为AwsUploadPolicy
; 在撰写本文时,它还不完整,但它可能会帮助其他遇到类似问题的人。
权限是最后一个问题;我的代码将 ACL 设置为public-read
,这样做需要额外的s3:PutObjectAcl
权限。
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:PutObject",
"s3:PutObjectAcl"
],
"Sid": "Stmt1379546195000",
"Resource": [
"arn:aws:s3:::upload.mydomain.com/uploads/*"
],
"Effect": "Allow"
}
]
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2706 次 |
最近记录: |