IAM 使用 javascript 向 AWS 授予对一种 dynamoDB 方法的访问权限,但不授予对另一种 dynamoDB 方法的访问权限
IAM Gives access to one dynamoDB method but not another using javascript to AWS
我在 Cognito 角色上定义了以下策略
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:Scan",
"dynamodb:UpdateItem"
],
"Resource": [
"arn:aws:dynamodb:ap-southeast-2: NUMBER:table/myapplication_product"
],
"Condition": {
"ForAllValues:StringEquals": {
"dynamodb:LeadingKeys": [
"${cognito-identity.amazonaws.com:sub}"
]
}
}
}
]
}
如您所见,它应该允许访问 GetItem、UpdateItem 和 Scan,但我发现只有 Scan 有效。尝试使用 GetItem 结果:
https://dynamodb.ap-southeast-2.amazonaws.com/ 400 (Bad Request)
Error: User: arn:aws:sts:: NUMBER:assumed-role/Cognito_XXXXX_IDUnauth_Role/CognitoIdentityCredentials is not authorized to perform: dynamodb:GetItem on resource: arn:aws:dynamodb:ap-southeast-2:NUMBER:table/myapplication_product(…)
我已经设置了:
AWS.config.region = 'ap-northeast-1'; // Region
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: 'ap-northeast-1:SECRET_UUID',
});
AWS.config.apiVersions = {
dynamodb: '2012-08-10',
};
this.dynamodb = new AWS.DynamoDB({region: "ap-southeast-2"});
那么为什么一种方法有效而另一种方法无效呢?
编辑
我想我还应该详细说明正在进行的实际查询。
这是扫描,它是基本的;只是为了显示所有产品
Store.prototype.getAllProducts = function(callback) {
var params = {
TableName: 'myapplication_product',
};
this.dynamodb.scan(params, callback);
}
这是 GetItem:
Store.prototype.getProduct = function (sku, callback) {
var params = {
TableName: 'stonesandpearls_product',
Key: {
sku: { S: sku }
},
};
this.dynamodb.getItem(params, callback);
}
如果我只使用:
AWS.config.update({accessKeyId: 'MY_SECRET_ID', secretAccessKey: 'MY_SECRET_ACCESS_KEY'});
这些查询有效,而不是 CognitoIdentityCredentials。
这里有几件事。
查看您的政策,您似乎正在寻找身份级别的细粒度访问权限。如果你想要它并且你将扫描添加到你的策略中,它基本上可以让任何身份访问你的完整 table。您应该只允许细粒度策略中的项目级别操作。 IAM roles for fine grained access control 对此进行了更详细的解释。
dynamodb:LeadingKeys 条件键将允许用户仅访问 partition/hash 键值与其身份 ID 匹配的项目。您收到的错误表明身份 ID 不是 DynamoDB table 中的散列键,或者您在发出获取或更新项目时未在 DynamoDB 查询中设置散列键值。这也是 Scan 工作的原因,因为扫描查询不需要哈希键值。
我在 Cognito 角色上定义了以下策略
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:Scan",
"dynamodb:UpdateItem"
],
"Resource": [
"arn:aws:dynamodb:ap-southeast-2: NUMBER:table/myapplication_product"
],
"Condition": {
"ForAllValues:StringEquals": {
"dynamodb:LeadingKeys": [
"${cognito-identity.amazonaws.com:sub}"
]
}
}
}
]
}
如您所见,它应该允许访问 GetItem、UpdateItem 和 Scan,但我发现只有 Scan 有效。尝试使用 GetItem 结果:
https://dynamodb.ap-southeast-2.amazonaws.com/ 400 (Bad Request)
Error: User: arn:aws:sts:: NUMBER:assumed-role/Cognito_XXXXX_IDUnauth_Role/CognitoIdentityCredentials is not authorized to perform: dynamodb:GetItem on resource: arn:aws:dynamodb:ap-southeast-2:NUMBER:table/myapplication_product(…)
我已经设置了:
AWS.config.region = 'ap-northeast-1'; // Region
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: 'ap-northeast-1:SECRET_UUID',
});
AWS.config.apiVersions = {
dynamodb: '2012-08-10',
};
this.dynamodb = new AWS.DynamoDB({region: "ap-southeast-2"});
那么为什么一种方法有效而另一种方法无效呢?
编辑
我想我还应该详细说明正在进行的实际查询。
这是扫描,它是基本的;只是为了显示所有产品
Store.prototype.getAllProducts = function(callback) {
var params = {
TableName: 'myapplication_product',
};
this.dynamodb.scan(params, callback);
}
这是 GetItem:
Store.prototype.getProduct = function (sku, callback) {
var params = {
TableName: 'stonesandpearls_product',
Key: {
sku: { S: sku }
},
};
this.dynamodb.getItem(params, callback);
}
如果我只使用:
AWS.config.update({accessKeyId: 'MY_SECRET_ID', secretAccessKey: 'MY_SECRET_ACCESS_KEY'});
这些查询有效,而不是 CognitoIdentityCredentials。
这里有几件事。
查看您的政策,您似乎正在寻找身份级别的细粒度访问权限。如果你想要它并且你将扫描添加到你的策略中,它基本上可以让任何身份访问你的完整 table。您应该只允许细粒度策略中的项目级别操作。 IAM roles for fine grained access control 对此进行了更详细的解释。
dynamodb:LeadingKeys 条件键将允许用户仅访问 partition/hash 键值与其身份 ID 匹配的项目。您收到的错误表明身份 ID 不是 DynamoDB table 中的散列键,或者您在发出获取或更新项目时未在 DynamoDB 查询中设置散列键值。这也是 Scan 工作的原因,因为扫描查询不需要哈希键值。