为什么我的访问在 s3 上被拒绝(使用 Node.js 的 aws-sdk)?
Why is my access denied on s3 (using the aws-sdk for Node.js)?
我正在尝试从我的 s3 存储桶中读取一个现有文件,但我一直收到 "Access Denied",但没有任何解释或说明如何处理它。 Here 是我使用的代码:
'use strict'
var AWS = require('aws-sdk')
const options = {
apiVersion: '2006-03-01',
params: {
Bucket: process.env['IMAGINATOR_BUCKET']
},
accessKeyId: process.env['IMAGINATOR_AWS_ACCESS_KEY_ID'],
secretAccessKey: process.env['IMAGINATOR_AWS_SECRET_ACCESS_KEY'],
signatureVersion: 'v4'
}
console.log('options', options)
var s3 = new AWS.S3(options)
module.exports = exports = {
get (name, cb) {
const params = {
Key: name + '.json'
}
console.log('get params', params)
return s3.getObject(params, cb)
},
set (name, body, cb) {
const params = {
Key: name + '.json',
Body: body
}
console.log('set params', params)
return s3.putObject(params, cb)
}
}
这就是我在使用 get
方法并记录回调中提供的错误时得到的输出(删除了敏感信息):
options { apiVersion: '2006-03-01',
params: { Bucket: CENSORED_BUT_CORRECT },
accessKeyId: CENSORED_BUT_CORRECT,
secretAccessKey: CENSORED_BUT_CORRECT,
signatureVersion: 'v4' }
get params { Key: 'whitelist.json' }
err { [AccessDenied: Access Denied]
message: 'Access Denied',
code: 'AccessDenied',
region: null,
time: Wed Sep 21 2016 11:17:50 GMT-0400 (EDT),
requestId: CENSORED,
extendedRequestId: CENSORED,
cfId: undefined,
statusCode: 403,
retryable: false,
retryDelay: 20.084538962692022 }
/Users/shawn/git/vigour-io/imaginate/node_modules/aws-sdk/lib/request.js:31
throw err;
^
AccessDenied: Access Denied
at Request.extractError (/Users/shawn/git/vigour-io/imaginate/node_modules/aws-sdk/lib/services/s3.js:538:35)
at Request.callListeners (/Users/shawn/git/vigour-io/imaginate/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
at Request.emit (/Users/shawn/git/vigour-io/imaginate/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
at Request.emit (/Users/shawn/git/vigour-io/imaginate/node_modules/aws-sdk/lib/request.js:668:14)
at Request.transition (/Users/shawn/git/vigour-io/imaginate/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/Users/shawn/git/vigour-io/imaginate/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /Users/shawn/git/vigour-io/imaginate/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/Users/shawn/git/vigour-io/imaginate/node_modules/aws-sdk/lib/request.js:38:9)
at Request.<anonymous> (/Users/shawn/git/vigour-io/imaginate/node_modules/aws-sdk/lib/request.js:670:12)
at Request.callListeners (/Users/shawn/git/vigour-io/imaginate/node_modules/aws-sdk/lib/sequential_executor.js:115:18)
现在我不确定该怎么做,因为我认为我根据文档正确地做事,但它不起作用并且错误消息没有说明为什么我的访问被拒绝...任何想法下一步应该怎么做才能让它发挥作用?
问题是我的新 IAM 用户没有附加策略。我为它分配了 AmazonS3FullAccess
策略,现在它起作用了。
正如评论中指出的那样,限制性更强的政策会更安全
您的政策中的 FullAccess
不是必需的。你可以尝试这样的事情:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:Put*",
"s3:Get*",
"s3:List*",
"s3:Delete*"
],
"Resource": [
"arn:aws:s3:::bucket/*",
"arn:aws:s3:::bucket"
]
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "s3:ListAllMyBuckets",
"Resource": "*"
}
]
}
当您尝试读取的对象不存在时,可能会出现这些错误。据我了解,在这些情况下,AWS 错误并不那么明显。
验证您的 key/bucket 是否正确以及您是否在 API 方法上发送正确的参数。
这个问题我已经遇到过两次了:
- 当我用存储桶参数替换键参数时,反之亦然,我试图使用
getObject()
方法读取 s3 对象。
- 当我尝试使用
copyObject()
方法将文件复制到不存在的位置时。
"code":"AccessDenied","region":null,"time":"2020-05-24T05:20:56.219Z","requestId": ...
在 s3 aws 控制台中应用了以下策略 > 'Permissions' 选项卡的存储桶策略编辑器 以消除上述错误,
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<IAM-user-ID>:user/testuser"
},
"Action": [
"s3:ListBucket",
"s3:ListBucketVersions",
"s3:GetBucketLocation",
"s3:Get*",
"s3:Put*"
],
"Resource": "arn:aws:s3:::srcbucket"
}
]
}
如果您尝试设置 ACL to "public-read" 但存储桶阻止 public 访问,也可能会发生这种情况。例如,如果您打算将静态资产上传到配置错误的 S3 存储桶。您可以在存储桶设置中更改它。
Steps
1: click on Users in IAM (in AWS)
2: click on permission tab
3: click on add permission then click on add group
4: search s3fullaccess in searchbar
5: select AmazonS3FullAccess and type any group name then click on create
6: perform action through your API again
7: done
在我的例子中,我更新了 .env
文件中保存 s3 存储桶名称的变量,但没有更新程序中的变量,因此程序接收到存储桶名称的 undefined
值导致我的程序抛出 access denied
错误的变量。
因此,如果您将存储桶名称存储在变量中,请确保使用正确的存储桶名称或正确的变量名称
我有同样的错误,这是因为我试图访问的文件不在存储桶中。因此,请确保您使用的是正确的存储桶名称,并且您要查找的文件的名称与该存储桶中存在的文件名称完全相同。
https://www.diffchecker.com/diff 是查找字符串差异的好工具
我正在尝试从我的 s3 存储桶中读取一个现有文件,但我一直收到 "Access Denied",但没有任何解释或说明如何处理它。 Here 是我使用的代码:
'use strict'
var AWS = require('aws-sdk')
const options = {
apiVersion: '2006-03-01',
params: {
Bucket: process.env['IMAGINATOR_BUCKET']
},
accessKeyId: process.env['IMAGINATOR_AWS_ACCESS_KEY_ID'],
secretAccessKey: process.env['IMAGINATOR_AWS_SECRET_ACCESS_KEY'],
signatureVersion: 'v4'
}
console.log('options', options)
var s3 = new AWS.S3(options)
module.exports = exports = {
get (name, cb) {
const params = {
Key: name + '.json'
}
console.log('get params', params)
return s3.getObject(params, cb)
},
set (name, body, cb) {
const params = {
Key: name + '.json',
Body: body
}
console.log('set params', params)
return s3.putObject(params, cb)
}
}
这就是我在使用 get
方法并记录回调中提供的错误时得到的输出(删除了敏感信息):
options { apiVersion: '2006-03-01',
params: { Bucket: CENSORED_BUT_CORRECT },
accessKeyId: CENSORED_BUT_CORRECT,
secretAccessKey: CENSORED_BUT_CORRECT,
signatureVersion: 'v4' }
get params { Key: 'whitelist.json' }
err { [AccessDenied: Access Denied]
message: 'Access Denied',
code: 'AccessDenied',
region: null,
time: Wed Sep 21 2016 11:17:50 GMT-0400 (EDT),
requestId: CENSORED,
extendedRequestId: CENSORED,
cfId: undefined,
statusCode: 403,
retryable: false,
retryDelay: 20.084538962692022 }
/Users/shawn/git/vigour-io/imaginate/node_modules/aws-sdk/lib/request.js:31
throw err;
^
AccessDenied: Access Denied
at Request.extractError (/Users/shawn/git/vigour-io/imaginate/node_modules/aws-sdk/lib/services/s3.js:538:35)
at Request.callListeners (/Users/shawn/git/vigour-io/imaginate/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
at Request.emit (/Users/shawn/git/vigour-io/imaginate/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
at Request.emit (/Users/shawn/git/vigour-io/imaginate/node_modules/aws-sdk/lib/request.js:668:14)
at Request.transition (/Users/shawn/git/vigour-io/imaginate/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/Users/shawn/git/vigour-io/imaginate/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /Users/shawn/git/vigour-io/imaginate/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/Users/shawn/git/vigour-io/imaginate/node_modules/aws-sdk/lib/request.js:38:9)
at Request.<anonymous> (/Users/shawn/git/vigour-io/imaginate/node_modules/aws-sdk/lib/request.js:670:12)
at Request.callListeners (/Users/shawn/git/vigour-io/imaginate/node_modules/aws-sdk/lib/sequential_executor.js:115:18)
现在我不确定该怎么做,因为我认为我根据文档正确地做事,但它不起作用并且错误消息没有说明为什么我的访问被拒绝...任何想法下一步应该怎么做才能让它发挥作用?
问题是我的新 IAM 用户没有附加策略。我为它分配了 AmazonS3FullAccess
策略,现在它起作用了。
正如评论中指出的那样,限制性更强的政策会更安全
FullAccess
不是必需的。你可以尝试这样的事情:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:Put*",
"s3:Get*",
"s3:List*",
"s3:Delete*"
],
"Resource": [
"arn:aws:s3:::bucket/*",
"arn:aws:s3:::bucket"
]
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "s3:ListAllMyBuckets",
"Resource": "*"
}
]
}
当您尝试读取的对象不存在时,可能会出现这些错误。据我了解,在这些情况下,AWS 错误并不那么明显。
验证您的 key/bucket 是否正确以及您是否在 API 方法上发送正确的参数。
这个问题我已经遇到过两次了:
- 当我用存储桶参数替换键参数时,反之亦然,我试图使用
getObject()
方法读取 s3 对象。 - 当我尝试使用
copyObject()
方法将文件复制到不存在的位置时。
"code":"AccessDenied","region":null,"time":"2020-05-24T05:20:56.219Z","requestId": ...
在 s3 aws 控制台中应用了以下策略 > 'Permissions' 选项卡的存储桶策略编辑器 以消除上述错误,
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<IAM-user-ID>:user/testuser"
},
"Action": [
"s3:ListBucket",
"s3:ListBucketVersions",
"s3:GetBucketLocation",
"s3:Get*",
"s3:Put*"
],
"Resource": "arn:aws:s3:::srcbucket"
}
]
}
如果您尝试设置 ACL to "public-read" 但存储桶阻止 public 访问,也可能会发生这种情况。例如,如果您打算将静态资产上传到配置错误的 S3 存储桶。您可以在存储桶设置中更改它。
Steps
1: click on Users in IAM (in AWS)
2: click on permission tab
3: click on add permission then click on add group
4: search s3fullaccess in searchbar
5: select AmazonS3FullAccess and type any group name then click on create
6: perform action through your API again
7: done
在我的例子中,我更新了 .env
文件中保存 s3 存储桶名称的变量,但没有更新程序中的变量,因此程序接收到存储桶名称的 undefined
值导致我的程序抛出 access denied
错误的变量。
因此,如果您将存储桶名称存储在变量中,请确保使用正确的存储桶名称或正确的变量名称
我有同样的错误,这是因为我试图访问的文件不在存储桶中。因此,请确保您使用的是正确的存储桶名称,并且您要查找的文件的名称与该存储桶中存在的文件名称完全相同。 https://www.diffchecker.com/diff 是查找字符串差异的好工具