Поместите файл в Amazon S3, используя многочастную загрузку - PullRequest
5 голосов
/ 24 января 2012

Я пытаюсь загрузить файл с помощью Amazon Java SDK, используя многочастную загрузку.Идея состоит в том, чтобы передать идентификатор загрузки апплету, который помещает части файла в контейнер только для чтения.Таким образом я избегаю хранения учетных данных AWS в апплете.

В своих тестах я генерирую идентификатор загрузки с помощью boto (python) и сохраняю файл в корзину.Это хорошо работает.

Мой апплет получает «403 Доступ запрещен» от S3, и я понятия не имею, почему.

Вот мой код (который частично взят из http://docs.amazonwebservices.com/AmazonS3/latest/dev/llJavaUploadFile.html):

AmazonS3 s3Client = new AmazonS3Client();
List<PartETag> partETags = new ArrayList<PartETag>();

long contentLength = file.length();
long partSize = Config.getInstance().getInt("part_size");
String bucketName = Config.getInstance().getString("bucket");
String keyName = "mykey";
String uploadId = getParameter("upload_id");

try {
    long filePosition = 0;
    for (int i = 1; filePosition < contentLength; i++) {

        partSize = Math.min(partSize, (contentLength - filePosition));

        // Create request to upload a part.
        UploadPartRequest uploadRequest = new UploadPartRequest()
            .withBucketName(bucket).withKey(keyName)
            .withUploadId(uploadId).withPartNumber(i)
            .withFileOffset(filePosition)
            .withFile(file)
            .withPartSize(partSize);

        // Upload part and add response to our list.
        partETags.add(s3Client.uploadPart(uploadRequest).getPartETag());

        filePosition += partSize;
    }

    System.out.println("Completing upload");
    CompleteMultipartUploadRequest compRequest = new 
                CompleteMultipartUploadRequest(bucket, 
                                            keyName, 
                                            uploadId, 
                                            partETags);

    s3Client.completeMultipartUpload(compRequest);
} catch (Exception e) {
    s3Client.abortMultipartUpload(new AbortMultipartUploadRequest(
            bucketName, keyName, uploadId));
}

В журнале отладки апплета я нахожу следующее:

INFO: Sending Request: PUT https://mybucket.s3.amazonaws.com /mykey Parameters: (uploadId: V4hwobOLQ1rYof54zRW0pfk2EfhN7B0fpMJTOpHOcmaUl8k_ejSo_znPI540.lpO.ZO.bGjh.3cx8a12ZMODfA--, partNumber: 1, ) Headers: (Content-Length: 4288546, Content-Type: application/x-www-form-urlencoded; charset=utf-8, ) 
24.01.2012 16:48:42 com.amazonaws.http.AmazonHttpClient handleErrorResponse
INFO: Received error response: Status Code: 403, AWS Service: null, AWS Request ID: DECF32CCFEE9EBF0, AWS Error Code: AccessDenied, AWS Error Message: Access Denied, S3 Extended Request ID: xtL1ixsGM2/vsxJ+cZRHpkPZ23SMfP8hZZjQCQnp8oWGwdS2/aGfYgomihyqaDCQ

Вы обнаружите какие-либо очевидные ошибки в коде?

Спасибо, Стефан

1 Ответ

7 голосов
/ 25 января 2012

Несмотря на то, что ваш вариант использования обоснован, и это действительно очевидная попытка, я не думаю, что Multipart Upload API был разработан для этого, и вы фактически нарушаете барьер безопасности:

Идентификатор загрузки является просто идентификатором, помогающим API Multipart Upload в сборке частей вместе (то есть больше похоже на временный объектный ключ), а не выделенным механизмом безопасности (см. Ниже). Следовательно, вам по-прежнему требуются надлежащие учетные данные для доступа, но поскольку вы звоните AmazonS3Client () , который создает новый клиент Amazon S3, который будет отправлять анонимные запросы в Amazon S3 , ваш запрос дает a 403 Доступ запрещен соответственно.

То, чего вы пытаетесь достичь, возможно с помощью Загрузка объектов с использованием предварительно подписанных URL-адресов , но, к сожалению, только без многокомпонентных функций:

Предварительно подписанный URL дает вам доступ к объекту, указанному в URL, при условии, что создатель предварительно подписанного URL-адреса имеет права на получить доступ к этому объекту. То есть, если вы получили предварительно подписанный URL для загрузки объект, вы можете загрузить объект, только если создатель Предварительно подписанный URL-адрес имеет необходимые разрешения для загрузки этого объекта.

[...] Предварительно подписанные URL полезны, если вы хотите, чтобы ваш пользователь / клиент мог загрузить определенную объект [...], но вам не требуется, чтобы они имели безопасность AWS учетные данные или разрешения. Когда вы создаете предварительно подписанный URL, вы должны укажите свои учетные данные безопасности, укажите имя группы объектов ключ, метод HTTP (PUT загрузки объектов) и срок действия и время. [...]

Длинная цитата иллюстрирует, почему система, подобная этой , вероятно , нуждается в более сложной схеме безопасности, чем "просто" раздача идентификатора загрузки (такой же, как могут показаться на первый взгляд).

Очевидно, что хотелось бы иметь возможность использовать обе функции вместе, но эта функция пока недоступна.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...