2015-08-08 1 views
1

Требование состоит в том, чтобы ограничить доступ пользователя IAM к определенной подпапке в ведре S3 через SDK AWS. Гораздо проще настроить политику пользователя с помощью консоли AWS, но я не смог, когда превратил ее в java-код с помощью AWS SDK.Почему двойная кавычка (") анализируется как (") в условном заявлении политики для пользовательской политики S3 при использовании AWS SDK?

Например, я хочу, чтобы пользователь IAM мог получить доступ к папке «подпапка1» в корзине «mybucket». Здесь ниже политик пользователя, который может отлично работать с консолью AWS: (Решение сами по себе доброжелательно относятся к here - которые я успешно проверен в AWS консоли)

{ 
    "Version": "2012-10-17", 
    "Statement": [ 
     { 
      "Sid": "1", 
      "Effect": "Allow", 
      "Action": [ 
       "s3:ListAllMyBuckets", 
       "s3:GetBucketLocation" 
      ], 
      "Resource": [ 
       "arn:aws:s3:::*" 
      ] 
     }, 
     { 
      "Sid": "2", 
      "Effect": "Allow", 
      "Action": [ 
       "s3:ListBucket" 
      ], 
      "Resource": [ 
       "arn:aws:s3:::mybucket" 
      ], 
      "Condition": { 
       "StringEquals": { 
        "s3:prefix": [ 
         "", 
         "subfolder1/" 
        ], 
        "s3:delimiter": [ 
         "/" 
        ] 
       } 
      } 
     }, 
     { 
      "Sid": "3", 
      "Effect": "Allow", 
      "Action": [ 
       "s3:PutObject", 
       "s3:GetObject", 
       "s3:DeleteObject" 
      ], 
      "Resource": [ 
       "arn:aws:s3:::mybucket/subfolder1/*" 
      ] 
     } 
    ] 
} 

Здесь под явой фрагмент кода для создания вышеуказанной политики.

// Attach the required permission user policy to the new user 
// 1. Permission to list all the buckets (view) 
final Statement allowListStatement = new Statement(Effect.Allow) 
    .withActions(
      S3Actions.ListBuckets, 
      S3Actions.GetBucketLocation 
     ) 
    .withResources(new Resource("arn:aws:s3:::*")); 

// 2. Permission to list the objects within the bucket 
final String dq = (char)(34) + ""; 
final String prefix = dq + dq + "," + dq + "subfolder1/" + dq; 

final Statement allowBucketListStatement = new Statement(Effect.Allow) 
.withActions(
     S3Actions.ListObjects 
    ) 
.withResources(
     new S3BucketResource(bucketName) 
    ) 
.withConditions(
     new StringCondition(
       StringComparisonType.StringEquals, 
       S3ConditionFactory.PREFIX_CONDITION_KEY, 
       prefix 
      ), 
     new StringCondition(
       StringComparisonType.StringEquals, 
       S3ConditionFactory.DELIMITER_CONDITION_KEY, 
       "/" 
      ) 
    ); 

// 3. Permission to update the bucket content 
final Statement allowBucketOperationsStatement = new Statement(Effect.Allow) 
    .withActions(
      S3Actions.PutObject, 
      S3Actions.GetObject, 
      S3Actions.DeleteObject 
     ) 
    .withResources(
      new S3ObjectResource(
        bucketName, 
        usernameIAM + "/*" 
       ) 
    ); 

final Policy policy = new Policy() 
    .withStatements(
      allowListStatement, 
      allowBucketListStatement, 
      allowBucketOperationsStatement 
     ); 

final PutUserPolicyRequest policyRequest = new PutUserPolicyRequest(
     usernameIAM, 
     "policy_subfolder1", 
     policy.toJson() 

    ); 
client.putUserPolicy(policyRequest); 

Проблема возникает в строке 'withConditions' (все остальные строки политики генерируются корректно, за исключением этой строки).

Ожидаемая линия будет, как это (который отлично работает в AWS консоли):

"Condition":{"StringEquals":{"s3:prefix":["","subfolder1/"], "s3:delimiter":["/"]}} 

Но реально генерируемой заключается в следующем:

"Condition":{"StringEquals":{"s3:prefix":["\"\",\"subfolder1/\""], "s3:delimiter":["/"]}} 

Это так странно, что AWS SDK каким-то образом не смог правильно проанализировать двойную кавычку ("): все двойные кавычки (") анализируются как (\ ").

Определение« префикса »кажется странным. В моем исходном коде я был U петь это:

final String prefix = "\"\",\"" + usernameIAM + "/\""; 

Но это дает ту же проблему, что и мой текущий подход (используя dq код ascii).

Я не уверен, что это ошибка в AWS SDK. Может ли кто-нибудь пролить свет на эту проблему? Или любой другой подход или предложение по выполнению моего требования (но должен использовать SDK)?


+1

'окончательного префикс String = дк + дк + "" + дк + "subfolder1 /" + дк;' <- * вы * добавляют кавычки самостоятельно. '' '' Как '' 'экранируется в JSON. Обратите внимание, что API ожидает * значение *, а не «ручной текст JSON». – user2864740

+0

Реальный вопрос, вероятно, заключается в следующем: «Как я могу использовать multi-'prefix» с StringCondition? » – user2864740

+0

Код в комментариях полностью испорчен. Я приложил свое решение в обновленном вопросе. Благодаря! – Shawshank

ответ

1

Благодаря пользователю2864740 за предложение. Настоящим я просто отправляю свой ответ на вопрос. Надеюсь, что другим может быть легче найти. Как указал user2864740, API ожидает значение, а не «ручной текст JSON», двойная кавычка («) будет обрабатываться с экранированным форматом (\).

Решение состоит в том, чтобы разделить StringCondition на разные части вместо того, чтобы генерировать строку JSON вручную. Вот окончательное осуществимое решение:

final String prefix1 = ""; 
final String prefix2 = "subfolder1/"; 
final Statement allowBucketListStatement = new Statement(Effect.Allow) 
.withActions(
     S3Actions.ListObjects 
    ) 
.withResources(
     new S3BucketResource(bucketName) 
    ) 
.withConditions(
     new StringCondition(
       StringComparisonType.StringEquals, 
       S3ConditionFactory.PREFIX_CONDITION_KEY, 
       prefix1 
      ), 
     new StringCondition(
       StringComparisonType.StringEquals, 
       S3ConditionFactory.PREFIX_CONDITION_KEY, 
       prefix2 
      ), 
     new StringCondition(
       StringComparisonType.StringEquals, 
       S3ConditionFactory.DELIMITER_CONDITION_KEY, 
       "/" 
      ) 
    ); 
Смежные вопросы