我想做一个 预先签名的 POST 以将文件上传到 AWS S3 存储桶- 在 Go 中这将如何完成?
请注意,这与使用 PUT 预签名上传不同。
我正在尝试使用签名URL将视频文件上传到云存储.HTTP put方法用于上传.当我尝试使用"HttpsUrl`连接"进行连接时,它会返回一些错误,如javax.net.ssl.SSLHandshakeException:握手失败.我该如何解决这个问题?这是我的代码:
URL url = new URL(url_string);
httpsUrlConnection = (HttpsURLConnection) url.openConnection();
httpsUrlConnection.setDoOutput(true);
httpsUrlConnection.setDoInput(true);
httpsUrlConnection.setRequestMethod(requestMethod);
httpsUrlConnection.setRequestProperty("Content-Type", "application/json");
httpsUrlConnection.setRequestProperty("Accept", "application/json");
httpsUrlConnection.connect();
Run Code Online (Sandbox Code Playgroud)
stacktrace就是这样的
javax.net.ssl.SSLHandshakeException: Handshake failed
com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:390c)
com.android.okhttp.Connection.upgradeToTls(Connection.java:201)
Run Code Online (Sandbox Code Playgroud) ssl android google-cloud-storage httpsurlconnection pre-signed-url
我们正在尝试使用AWS S3存储文件。我们在JAVA中创建了一个简单的REST API,以上传和检索文件。
要求更新文件的客户使用我们的REST API,该API提供一个预签名的URL来PUT / GET文件。我们正在使用适用于Java的AWS开发工具包来生成预签名的URL。
在S3上更新文件时,我们需要向文件中添加一些自定义元数据。由于我们不控制上传到S3本身,因此有什么方法可以在生成预签名的url时添加此信息?让客户端将这些信息作为其请求标头的一部分提供,这将是不好的。
客户端应用程序请求S3的预签名URL.目前,我们限制URL有效的时间,但也希望将其限制为客户端的IP地址.
是否可以创建限于特定IP地址的S3预签名URL?
据我所知,只有CloudFront会让我这样做.
情况:我在网络中运行一个 Django 应用程序,登录用户还可以下载 .pdf 文件(非公开,有特定限制,具体取决于用户权限)。最方便的方法(例如在 S3 中)是使用有时间限制的预签名 URL,因为它们会立即在浏览器中打开,而且应用程序服务器无需处理额外的流量。
问题:Backblaze B2 显然没有提供明确的方法来创建预签名 URL 以直接在浏览器中下载非公开文件。生成 api URL 和授权令牌以及从对象存储中获取文件发生在应用程序服务器级别,并且该过程不会向“普通”用户公开。
但最终,API 操作“b2_download_file_by_name”仅使用 GET 请求,这意味着我可以使用“?Authorization=123xyz........”将授权令牌添加到请求的 URL。这样我就可以获得一个在浏览器中完美运行的预签名 URL,以允许在有限的时间内访问特定的非公开文件。(请注意:B2 下载可以限制为具有特定前缀的文件 [如 s3 伪文件夹],但如果指定的“前缀”足够长,我可以使身份验证令牌特定于一个文件。)
问题:正如我上面所写,通常授权令牌不会暴露给用户。现在,如果我使 URL 可见,这是否意味着存在安全风险?换句话说,拥有一个或多个令牌的用户是否可以从令牌中提取通用访问密钥,或者令牌是否加密得足以避免这种情况?
我正在生成一个预先签名的 URL 服务器端,以允许我的客户端应用程序将文件直接上传到 S3 存储桶。除非客户端应用程序在技术上比我的服务器时钟早一天的时区中的计算机上运行,否则一切正常。
我可以通过将系统时钟提前到第二天的时区来在本地重新创建问题。
这是我使用 .NET SDK 生成预签名 URL 的方式(我最初使用的是 DateTime.Now 而不是 UTCNow):
var request = new GetPreSignedUrlRequest
{
BucketName = bucketName,
Key = objectName,
Verb = HttpVerb.PUT,
Expires = DateTime.UtcNow.AddDays(5),
ContentType = "application/octet-stream"
};
request.Headers["x-amz-acl"] = "bucket-owner-full-control";
request.Metadata.Add("call", JsonConvert.SerializeObject(call).ToString());
return client.GetPreSignedURL(request);
Run Code Online (Sandbox Code Playgroud)
然后我在客户端应用程序中使用该预签名 URL,如下所示:
using (var fileStream = new FileStream(recordingPath, FileMode.Open))
using (var client = new WebClient())
{
HttpContent fileStreamContent = new StreamContent(fileStream);
var bytes = await fileStreamContent.ReadAsByteArrayAsync();
client.Headers.Add("Content-Type", "application/octet-stream");
//include metadata in PUT request
client.Headers.Add("x-amz-meta-call", JsonConvert.SerializeObject(Call));
await …Run Code Online (Sandbox Code Playgroud) 我正在尝试按照文档 ( https://docs.aws.amazon.com/AmazonS3/latest/dev/PresignedUrlUploadObject.html )中的描述使用预先签名的 URL 进行上传,我可以检索预先签名的 URL,但是当我尝试在 Postman 中执行 PUT,收到以下错误:
<Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
Run Code Online (Sandbox Code Playgroud)
显然,我的 put 调用的结构方式与 AWS 计算签名的方式不匹配。我找不到很多关于这个看跌调用需要什么的信息。
我试图将 Content-Type 的标头修改为 multipart/form-data 和 application/octet-stream。我还尝试在 postman 中取消勾选 headers 部分,并依赖正文类型来选择文件的表单数据和二进制设置。表单数据设置导致以下添加到调用中:
内容配置:表单数据;name="thefiletosend.txt"; 文件名="thefiletosend.txt
此外,我注意到邮递员包括它所谓的“临时标题”,如下所示:
主机:s3.amazonaws.com Content-Type:text/plain User-Agent:PostmanRuntime/7.13.0 Accept:/ Cache-Control:no-cache Postman-Token:e11d1ef0-8156-4ca7-9317-9f4d22daf6c5,2135bc0e-128 -4438-bb8e-b21d31dc36db 主机:s3.amazonaws.com 接受编码:gzip,放气内容长度:14 连接:保持活动缓存控制:无缓存
Content-Type 标头可能是问题之一,但我不确定如何在邮递员中排除这些“临时标头”。
我在 lambda 中生成预先签名的 URL,如下所示:
public string FunctionHandler(Input input, ILambdaContext context)
{
_logger = context.Logger;
_key = input.key;
_bucketname = input.bucketname; …Run Code Online (Sandbox Code Playgroud) 我正在使用 gsutil 创建用于上传的预签名 URL。当命名桶中的对象时,我可以成功上传。gsutil 中的以下 snipit 可以与curl PUT 配合使用:
gsutil signurl -m PUT -d 10m -r eu ~/.ssh/mycreds.json gs://cjreyn-bucket-0/myobjectname.txt
Run Code Online (Sandbox Code Playgroud)
但是,当仅指定存储桶名称而不是其中的对象时,上传任意对象不起作用:
gsutil signurl -m PUT -d 10m -r eu ~/.ssh/mycreds.json gs://cjreyn-bucket-0/
Run Code Online (Sandbox Code Playgroud)
这会从curl 返回以下内容:
<?xml version='1.0' encoding='UTF-8'?><Error><Code>BucketAlreadyOwnedByYou</Code><Message>Your previous request to create the named bucket succeeded and you already own it.</Message></Error>
Run Code Online (Sandbox Code Playgroud)
我的curl行如下(为简洁起见,将签名的URL替换为):
curl -X PUT --upload-file myobj.txt "<mysignedurl>"
Run Code Online (Sandbox Code Playgroud)
是否甚至可以创建签名 URL 以用于向/从整个存储桶上传和下载,而不是针对其中的每个对象?
amazon-s3 amazon-web-services gsutil pre-signed-url google-cloud-platform
create_presigned_post想要将自定义元数据添加到我使用boto3上传的文件中。我正在运行以下代码,但收到 403 响应。下面的代码是从这里借来的。难道我做错了什么?
def create_presigned_post(bucket_name, object_name,
fields=None, conditions=None, expiration=3600):
# Generate a presigned S3 POST URL
s3_client = boto3.client('s3')
try:
response = s3_client.generate_presigned_post(bucket_name,
object_name,
Fields=fields,
Conditions=conditions,
ExpiresIn=expiration)
except ClientError as e:
print(e)
return None
# The response contains the presigned URL and required fields
return response
# Generate a presigned S3 POST URL
object_name = 'test-file.txt'
response = create_presigned_post('temp', object_name, fields={'x-amz-meta-test_key': 'test_val'})
# Demonstrate how another Python program can use the presigned URL to upload a file …Run Code Online (Sandbox Code Playgroud) metadata amazon-s3 http-status-code-403 pre-signed-url boto3
我已成功使用 boto3 生成 Amazon S3 签名 URL。
import logging
import boto3
from botocore.exceptions import ClientError
def create_presigned_url(bucket_name, object_name, expiration=3600):
"""Generate a presigned URL to share an S3 object
:param bucket_name: string
:param object_name: string
:param expiration: Time in seconds for the presigned URL to remain valid - 1 hour in this case
:return: Presigned URL as string. If error, returns None.
"""
# Generate a presigned URL for the S3 object
s3_client = boto3.client('s3')
try:
response = s3_client.generate_presigned_url('get_object', Params={'Bucket': bucket_name, …Run Code Online (Sandbox Code Playgroud) pre-signed-url ×10
amazon-s3 ×8
boto3 ×2
metadata ×2
android ×1
aws-sdk ×1
aws-sdk-net ×1
backblaze ×1
go ×1
gsutil ×1
ip-address ×1
java ×1
postman ×1
python ×1
ssl ×1