对 DynamoDb 使用细粒度访问控制时出现 AccessDeniedException
Posted
技术标签:
【中文标题】对 DynamoDb 使用细粒度访问控制时出现 AccessDeniedException【英文标题】:AccessDeniedException when using Fine-Grained Access control for DynamoDb 【发布时间】:2021-10-01 00:38:46 【问题描述】:我在 API 网关(准确地说是 Apollo 服务器)后面有一个 lambda 函数,我通过一个 React 应用程序访问它,方法是传递我在使用 Amplify Auth 登录后获得的 JWT IdToken。
但是,当我尝试运行此应用程序时,我不断得到:
AccessDeniedException:用户:arn:aws:sts::AWS 账户 ID:assumed-role/shop-app-xxx-XXX-CognitoAuthorizedRole-XXXXXXXXXX/CognitoIdentityCredentials 无权执行:dynamodb:GetItem on resource:arn:aws :dynamodb:us-east-1:AWS Account ID:table/Shop"
我的角色策略中的以下条件导致了这种情况(完整角色/策略见下文)。我不太了解我的政策是否有问题,或者我获取凭据的方式是否有问题。我的角色中的 sts:AssumeRoleWithWebIdentity
操作是否导致我不再使用 cognito 身份访问资源?
Condition:
ForAllValues:StringEquals:
dynamodb:LeadingKeys:
- "$cognito-identity.amazonaws.com:sub
const identityToken = event.headers.Authorization;
AWS.config.credentials = new AWS.CognitoIdentityCredentials(
IdentityPoolId: `$process.env.IDENTITY_POOL_ID`,
Logins:
[`cognito-idp.$awsConfig.region.amazonaws.com/$process.env.USER_POOL_ID`]: identityToken
);
(AWS.config.credentials as AWS.CognitoIdentityCredentials).refresh(function(err)
if(!err)
console.log("no error");
let dynamoDbClient:AWS.DynamoDB.DocumentClient = new AWS.DynamoDB.DocumentClient();
getShopModel(user,dynamoDbClient).shop().then((shop)=>console.log(shop));
else
console.log("got an error!");
console.log(err);
);
以下是我的授权角色和映射。如果我从内联策略中删除了 LeadingKeys 条件,那么一切正常。但是我当然没有细粒度的控制。
CognitoAuthorizedRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Federated: "cognito-identity.amazonaws.com"
Action:
- "sts:AssumeRoleWithWebIdentity"
Condition:
StringEquals:
"cognito-identity.amazonaws.com:aud": !Ref ShopIdentityPool
"ForAnyValue:StringLike":
"cognito-identity.amazonaws.com:amr": authenticated
Policies:
- PolicyName: "CognitoAuthorizedPolicy"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- "cognito-sync:*"
- "cognito-identity:*"
Resource: "*"
- Effect: "Allow"
Action:
- "lambda:InvokeFunction"
Resource: "*"
- Effect: Allow
Action:
- 'dynamodb:GetItem'
- 'dynamodb:PutItem'
- 'dynamodb:Query'
- 'dynamodb:Scan'
- 'dynamodb:Delete*'
- 'dynamodb:Update*'
Resource: [
!Sub "arn:aws:dynamodb:$AWS::Region:*:table/$ShopTable",
!Sub "arn:aws:dynamodb:$AWS::Region:*:table/$ShopTable/index/*"]
Condition:
ForAllValues:StringEquals:
dynamodb:LeadingKeys:
- "$cognito-identity.amazonaws.com:sub"
ShopIdentityPoolRoleMapping:
Type: "AWS::Cognito::IdentityPoolRoleAttachment"
Properties:
IdentityPoolId: !Ref ShopIdentityPool
Roles:
authenticated: !GetAtt CognitoAuthorizedRole.Arn
unauthenticated: !GetAtt CognitoUnAuthorizedRole.Arn
【问题讨论】:
【参考方案1】:似乎 yaml 和 json 在 Resource 部分混合在一起。
从
更改资源部分Resource: [
!Sub "arn:aws:dynamodb:$AWS::Region:*:table/$ShopTable",
!Sub "arn:aws:dynamodb:$AWS::Region:*:table/$ShopTable/index/*"]
到
Resource:
- !Sub "arn:aws:dynamodb:$AWS::Region:*:table/$ShopTable",
- !Sub "arn:aws:dynamodb:$AWS::Region:*:table/$ShopTable/index/*"
【讨论】:
不幸的是,这并没有解决它@shimo。如果将其更改为正确的 yaml 结构,但似乎 cloudformation 并不介意。还有其他想法吗?$cognito-identity.amazonaws.com:sub
用于身份 ID。如果您使用的是身份池,请改用...:aud
。
感谢@shimo。我想知道为什么我需要使用 :aud 值来代替?您是说因为我使用联合身份登录,所以子值不可用?这似乎很奇怪。我也使用 sub 在 dynamodb 中创建了我的记录。
对不起,如果不起作用。我注意到 id pool 用于查看您的代码,并在 this aws blog 中找到了带有 aud 的策略条件。以上是关于对 DynamoDb 使用细粒度访问控制时出现 AccessDeniedException的主要内容,如果未能解决你的问题,请参考以下文章
IAM 策略条件中的 cognito 用户池自定义属性与 Dynamodb 细粒度访问