首页 > 解决方案 > 在 Python 中生成一个预签名的 URL,然后在 Java 中使用它

问题描述

我有一个 Java-Python 集成问题,我收到了来自 Python Lambda 的预签名 URL,而 Java 桌面客户端实际上正在使用该 URL 来执行多部分上传。

我面临的问题的本质是 Python 和 Java 使用预签名 URL 的方式完全不同。Python 使用 JSON 对象,例如

{"url":"https://some-bucket-us-west-2.s3.amazonaws.com/","fields":{"key":"my_object_key","AWSAccessKeyId":"XXXXXXXXXXX","x-amz-security-token":"my_token","policy":"my_policy","signature":"my_sig"}}

Python 中预签名 URL 的示例用法:

requests.post(returned_url_response['url'], data=returned_url_response['fields'], files=files)

然而,Java 使用以某种方式参数化/编码的实际 URL:

https://my-bucket-us-west-2.s3.us-west-2.amazonaws.com/caseId%3D02_mock/dummy.encrypted?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date= 20210924T184139Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3599&X-Amz-Credential=some_credentialFaws4_request&X-Amz-Signature=some_hash

Java 中预签名 URL 的示例用法:

URL url = s3Client.generatePresignedUrl(generatePresignedUrlRequest);


// Create the connection and use it to upload the new object using the pre-signed URL.
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("PUT");
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream())

我的问题是,是否有一个 Java 等价物来做我在 Python 中所做的事情,以便我仍然可以使用 Python 生成的输出?

或者generate_presigned_url(),在 Python lambda 中使用会生成一个我可以从 Java 应用程序使用的 URL?我需要为每个 ClientMethod 操作生成一个预签名的 URLcreate_multipart_upload, upload_part, complete_multipart_upload吗?

最后,这两种方法中的任何一种都比扔掉我的 Python Lambda 并制作一个生成预签名 URL 的 Java Lambda 更可取吗?

标签: pythonjavaamazon-web-servicesaws-lambdaboto3

解决方案


Python 还可以为任何 HTTP 方法生成一体化编码 URL,因为这是预签名 URL 的默认形式。我创建了一个测试 python 脚本只是为了确保一切正常。如果您运行此程序(在导出您的凭证并用适当的存储桶/对象键替换变量之后),您将获得一个编码后的 URL 输出到控制台:

import boto3

s3 = boto3.client('s3')
url = s3.generate_presigned_url('put_object', Params={'Bucket': bucket, 'Key': object_key},
                                ExpiresIn=expirationInSeconds,  
                                HttpMethod=method)

print(url)

您可能正在使用,它返回一个字典而不是您的 python lambda 的 URL,但是只要您确保传入正确的 HttpMethod generate_presigned_post,post 操作就可以正常工作。generate_presigned_url参考


推荐阅读