2017-01-31 3 views
0

У меня есть таблица с некоторыми элементами. Я пытаюсь использовать Fine-Grained Access Control (Ограничить доступ к конкретным атрибутам в таблице) на unauth (я хочу вернуть определенные атрибуты для пользователя, которые еще не прошли проверку подлинности), когда пользователь просматривает определенные атрибуты на основе следующего URL-адреса Using IAM Policy Conditions for Fine-Grained Access Control.Amazon DynamoDB: мелкозернистый контроль доступа Сканирование с определенными атрибутами

{ 
"Version": "2012-10-17", 
"Statement": [ 
    { 
     "Sid": "LimitAccessToSpecificAttributes", 
     "Effect": "Allow", 
     "Action": [ 
      "dynamodb:GetItem", 
      "dynamodb:Query", 
      "dynamodb:BatchGetItem", 
      "dynamodb:Scan" 
     ], 
     "Resource": [ 
      "arn:aws:dynamodb:us-west-2:AccountID:table/MyTable" 
     ], 
     "Condition": { 
      "ForAllValues:StringEquals": { 
       "dynamodb:Attributes": [ 
        "startDate", 
        "endDate" 
       ] 
      }, 
      "StringEqualsIfExists": { 
       "dynamodb:Select": "SPECIFIC_ATTRIBUTES", 
       "dynamodb:ReturnValues": [ 
        "NONE", 
        "UPDATED_OLD", 
        "UPDATED_NEW" 
       ] 
      } 
     } 
    } 
] 
} 

когда я удаления следующей роли она работает:

"Condition": { 
      "ForAllValues:StringEquals": { 
       "dynamodb:Attributes": [ 
        "startDate", 
        "endDate" 
       ] 
      }, 
      "StringEqualsIfExists": { 
       "dynamodb:Select": "SPECIFIC_ATTRIBUTES", 
       "dynamodb:ReturnValues": [ 
        "NONE", 
        "UPDATED_OLD", 
        "UPDATED_NEW" 
       ] 
      } 

проблема заключается в том, что, когда я бегу мой код (Android) я получаю следующее исключение:

Пользователь: arn: aws: sts :: AccountID: Предполагаемая роль/Cognito_XXXUnauth_Role/CognitoIdentityCredentials не имеет права выполнять: dynamodb: Scan on resource: arn: aws: dynamodb: us-east-1: AccountID: table/MyTable (Услуга: AmazonDynamoDB; Код состояния: 400; Код ошибки: AccessDeniedException;

Я хотел бы знать, что я делаю неправильно, что вызывает исключение. Есть ли другой способ получить конкретные атрибуты?

Я использую следующий код андроида:

CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(getApplicationContext(), 
         "identityPoolId", 
         Regions.US_EAST_1 
       ); 

AmazonDynamoDBClient ddb = new AmazonDynamoDBClient(credentialsProvider); 

ScanRequest scanRequest = new ScanRequest(); 
scanRequest = scanRequest.withProjectionExpression("startDate, endDate"); 
scanRequest.setTableName("MyTable"); 

try { 
    ScanResult scanResult = ddb.scan(scanRequest); 
} catch (Exception ex) { 
    log(ex.getMessage()); 
} 

Любая помощь будет оценена.

ответ

0

Я нашел причину. Атрибуты в роли должны включать ключи hashkey и range. При замене атрибутов клавишей hashkey и диапазона я получил его работу, также меняя регион, как ответила Лиза.

Я буду размещать здесь политику и андроида код в случае, если кто в будущем хотел бы видеть, как это должно быть сделано:

{ 
"Statement": [ 
    { 
     "Effect": "Allow", 
     "Action": [ 
      "dynamodb:DeleteItem", 
      "dynamodb:GetItem", 
      "dynamodb:PutItem", 
      "dynamodb:Scan", 
      "dynamodb:Query", 
      "dynamodb:UpdateItem", 
      "dynamodb:BatchWriteItem" 
     ], 
     "Resource": [ 
      "arn:aws:dynamodb:us-east-1:AcountID:table/MyTable", 
      "arn:aws:dynamodb:us-east-1:AcountID:table/MyTable/index/*" 
     ] 
    } 
]} 

политики для анонимных пользователей:

{ 
"Version": "2012-10-17", 
"Statement": [ 
    { 
     "Sid": "LimitAccessToSpecificAttributes", 
     "Effect": "Allow", 
     "Action": [ 
      "dynamodb:GetItem", 
      "dynamodb:Query", 
      "dynamodb:BatchGetItem", 
      "dynamodb:Scan" 
     ], 
     "Resource": [ 
      "arn:aws:dynamodb:us-east-1:AcountID:table/MyTable" 
     ], 
     "Condition": { 
      "ForAllValues:StringEquals": { 
       "dynamodb:Attributes": [ 
        "userId", 
        "startDate", 
        "endDate", 
        "Price" 
       ] 
      }, 
      "StringEqualsIfExists": { 
       "dynamodb:Select": "SPECIFIC_ATTRIBUTES" 
      } 
     } 
    } 
]} 

андроид код содержит код для аутентифицированного и не прошедшего проверку пользователя (беспорядочный).

public PaginatedScanList<Book> scan() { 

    PaginatedScanList<Book> result = null; 
    AmazonDynamoDBClient ddb = new AmazonDynamoDBClient(_cognito.getCredentialsProvider()); 

    if (_cognito.getJWTToken() != null) { 
     //Authenticated (SignedIn) user flow 
     _cognito.credentialsProviderSetLogIn(); 
     mapper = new DynamoDBMapper(ddb); 

     DynamoDBScanExpression scanExpression = new DynamoDBScanExpression(); 
     result = mapper.scan(Book.class, scanExpression); 

     if (result != null) { 
      for (int i = 0; i < result.size(); i++) { 
       log("UserId: " + result.get(i).getUserId()); 
       log("Price: " + result.get(i).getPrice()); 
       log("startDate: " + result.get(i).getPrice()); 
       log("endDate: " + result.get(i).getPrice()); 
      } 
     } 
    } else { 
     //UnAuthenticated user flow 
     ScanRequest scanRequest = new ScanRequest(); 
     //Write attributes to be retreived. if Price is not exsits, items.get(i).get("Price").getS() will be null 
     //If Price is not exists in the policy, policy is null 
     scanRequest = scanRequest.withProjectionExpression("UserId, Price, startDate, endDate");//setter for projectionExpression 
     //scanRequest.setProjectionExpression("UserId, Price, startDate, endDate"); //not sure why this API exists. It does the same as withProjectionExpression. this is setter for projectionExpression 
     scanRequest.setSelect(Select.SPECIFIC_ATTRIBUTES); //Not usre this is needed. works well without it. 
     scanRequest.setTableName("MyTable"); 

     try { 
      ScanResult scanResult = ddb.scan(scanRequest); 
      final List<Map<String, AttributeValue>> items = scanResult.getItems(); 

      for (int i = 0; i < items.size(); i++) { 
       log("UserId: " + items.get(i).get("UserId").getS()); 
       log("Price: " + items.get(i).get("Price").getS()); 
       log("startDate: " + items.get(i).get("startDate").getS()); 
       log("endDate: " + items.get(i).get("endDate").getS()); 
      } 
     } catch (Exception ex) { 
      log(ex.getMessage()); 
     } 
    } 

    return result; 
} 
1

Посмотрите на свою политику IAM, похоже, что на ресурсе разрешена операция сканирования: arn: aws: dynamodb: us-west-2: AccountID: table/MyTable.

Обратите внимание, что ресурс для нас-запад-2. Но вы пытаетесь выполнить операцию на ресурсе в us-east-1.

0

Убедитесь, что в пуле идентификации достаточно лицензий DynamoDB, в этом случае для выполнения сканирования. Вот пример использования Cognito путем создания неаутентифицированный роли и предоставления ему доступа DynamoDB: http://docs.aws.amazon.com/amazondynamodb/latest/gettingstartedguide/GettingStarted.Js.Summary.html

Тогда, как другой человек сказал, убедитесь, что вы указываете в том же регионе вы предоставления разрешений. В этом случае убедитесь, что у US_EAST_1 достаточно доступа Cognito и DDB.

Смежные вопросы