2017-01-31 1 views
0

Ich habe eine Tabelle mit einigen Elementen. Ich versuche, feinkörnige Zugriffssteuerung (Zugriff auf bestimmte Attribute in einer Tabelle beschränken) auf unauth (ich möchte bestimmte Attribute für Benutzer, die noch nicht authentifiziert sind), wo Benutzer auf bestimmte Attribute basierend auf folgenden URL Using IAM Policy Conditions for Fine-Grained Access Control.Amazon DynamoDB: feinkörnige Zugriffskontrolle Scannen mit spezifischen Attributen

{ 
"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" 
       ] 
      } 
     } 
    } 
] 
} 

wenn ich folgende Rolle bin Entfernen funktioniert es:

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

Das Problem ist, dass, wenn ich meinen Code leite (android) ich folgende Ausnahme bin immer:

Benutzer: arn: aws: sts :: AccountID: angenommen-Rolle/Cognito_XXXUnauth_Role/CognitoIdentityCredentials ist nicht erlaubt zu erfüllen: dynamodb: Scan auf Ressource: arn: aws: dynamodb: us-east-1: AccountID: table/MyTable (Dienst: AmazonDynamoDB; Statuscode: 400; Fehlercode: AccessDeniedException;

Ich würde gerne wissen, was ich falsch mache, die die Ausnahme verursacht. Gibt es eine andere Möglichkeit, bestimmte Attribute zu erhalten?

ich folgenden Android Code verwenden:

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()); 
} 

Jede Hilfe würde geschätzt.

Antwort

0

Ich fand den Grund. Die Attribute in der Rolle sollten Hash-Schlüssel und Bereichsschlüssel enthalten. Als ich die Attribute durch einen Hash-Schlüssel und einen Bereichsschlüssel ersetzte, bekam ich Arbeit und änderte auch die Region, als Lisa antwortete.

Ich werde hier posten die Politik und die Android-Code, falls jemand in die Zukunft sehen möchten, wie es getan werden sollte:

{ 
"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/*" 
     ] 
    } 
]} 

Politik für nicht authentifizierte Benutzer:

{ 
"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" 
      } 
     } 
    } 
]} 

android Code enthält Code für authentifizierte und nicht authentifizierte Benutzer (unordentlich).

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

Wenn Sie Ihre IAM-Richtlinie betrachten, sieht es so aus, als wäre die Scan-Operation auf der Ressource erlaubt: arn: aws: dynamodb: us-west-2: AccountID: table/MyTable.

Beachten Sie, dass die Ressource für uns-West-2 ist. Sie versuchen jedoch, die Operation für eine Ressource in us-east-1 auszuführen.

0

Stellen Sie sicher, dass der Identitätspool über genügend DynamoDB-Berechtigungen verfügt, um in diesem Fall Scans durchzuführen. Hier ist ein Beispiel Cognito der Verwendung von einer nicht authentifizierte Rolle zu schaffen und es DynamoDB Zugang gewähren: http://docs.aws.amazon.com/amazondynamodb/latest/gettingstartedguide/GettingStarted.Js.Summary.html

Dann wird, wie die andere Person sagte, stellen Sie sicher, dass Sie in der gleichen Region weisen Sie Berechtigungen erteilen. Stellen Sie in diesem Fall sicher, dass US_EAST_1 über genügend Cognito und DDB-Zugriff verfügt.

Verwandte Themen