Java-эквивалент клиента AWS S3 Python "generate_presigned_post" - PullRequest
1 голос
/ 24 июня 2019

В библиотеке Python boto3 есть метод generate_presigned_post, который позволяет создать предварительно подписанный URL для загрузки файла с помощью POST.Я не вижу эквивалента в Java, поскольку доступные вещи («GeneratePresignedUrlRequest») поддерживают только: GET, PUT, DELETE, HEAD.

Интересно, если я что-то упустил, или если люди могут придумать способвозможно, просто сделать это, написав свой собственный generatePresignedPost на Java?

Я строю сервис на Java, где хочу вернуть предварительно подписанный URl, позволяющий загружать несколько файлов в определенный префикс bucket / key вS3.

Сначала я сделал несколько прототипов в Python, чтобы понять больше и получил этот код:

bucket_name = "my-bucket"
key = "test/${filename}"
expires_in = 24*60*60 # 1 day

s3_client = # Initialize Boto S3 Client with Credentials

response = s3_client.generate_presigned_post(bucket_name, key, ExpiresIn=expires_in)

print(response['url'])
print(response['fields'])

(я знаю, что "$ {filename}" преобразуется в "start-width "condition)

Java-версия GeneratePresignedUrlRequest позволяет только создавать предварительно подписанные URL-адреса PUT, но не позволяет мне устанавливать« condition »как POST-версию.Вот почему я хочу получить эквивалент generate_presigned_post в Java.

В результате код Python создает запрос, который выглядит следующим образом:

fields = {'key': 'test/${filename}'}
conditions = [{'bucket': 'my-bucket'}, ['starts-with', '$key', 'test/']]
request_dict = {'url_path': '/my-bucket', 'query_string': {}, 'method': 'PUT', 'headers': {}, 'body': b'', 'url': 'https://s3.us-west-2.amazonaws.com/my-bucket', 'context': {'is_presign_request': True, 'use_global_endpoint': True}}

И то, что возвращается, выглядит так:

response['url'] = 'https://my-bucket.s3.amazonaws.com/'
response['fields'] = {'key': 'test/${filename}', 'AWSAccessKeyId': 'ACCESS_KEY', 'x-amz-security-token': 'SECURITY_TOKEN', 'policy': 'VERY_LONG_POLICY', 'signature': 'SIGNATURE'}

Ответы [ 2 ]

1 голос
/ 24 июня 2019

Вы можете использовать следующий фрагмент кода

GeneratePresignedUrlRequest generatePresignedUrlRequest = 
                new GeneratePresignedUrlRequest(bucketName, objectKey)
                .withMethod(HttpMethod.POST)
                .withExpiration(expiration);
URL url = s3Client.generatePresignedUrl(generatePresignedUrlRequest);

Вы можете проверить здесь для полной версии Java Source

0 голосов
/ 24 июня 2019

Нашли статьи из Amazon: https://aws.amazon.com/articles/browser-uploads-to-s3-using-html-post-forms/

Этот способ работает для генерации подписи:

import sun.misc.BASE64Encoder;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

String policy = (new BASE64Encoder()).encode(
    policy_document.getBytes("UTF-8")).replaceAll("\n","").replaceAll("\r","");

Mac hmac = Mac.getInstance("HmacSHA1");
hmac.init(new SecretKeySpec(
    aws_secret_key.getBytes("UTF-8"), "HmacSHA1"));
String signature = (new BASE64Encoder()).encode(
    hmac.doFinal(policy.getBytes("UTF-8")))
    .replaceAll("\n", "");

Все равно было бы намного проще, если бы он был легко доступен из AmazonS3Client.

...