問題標題很寬泛,但我的問題不是。我只想澄清我的方法。我有一個阻止公共訪問的 s3 存盤桶。存盤桶策略設定為 http-referer。這是它的樣子。
{
"Version": "2008-10-17",
"Id": "http referer policy example",
"Statement": [
{
"Sid": "Allow get requests referred by www.mysite.com and mysite.com",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::storage/*",
"Condition": {
"StringLike": {
"aws:Referer": [
"https://www.example.com/*",
"https://example.com/*",
]
}
}
}
]
}
如果我的前端(在我的 tld 上)嘗試通過 URL 訪問 s3 資源,我仍然會收到錯誤訊息。(網址示例 - https://storage.s3.amazonaws.com/path/to/my/file.png)。
我放棄了直接訪問 s3 URL 的方法,并決定在我的 TLD 上構建一個后端實用程式,它將獲取有問題的 s3 資源并將其發送回前端。所以 URL 看起來像這樣,https://<tld>/fetch-s3-resource/path/to/file.png.
我想知道這種方法是否正確,或者是否有更好的方法。在我看來,即使設定 http-referer 策略也沒有意義,因為任何人都可以通過手動將 http-referer 設定為我的 TLD 來呼叫我的存盤桶。
更新- 我發現簽名 URL 應該允許用戶通過 URL 公開訪問資源。這應該可以解決我的問題,但我仍然將公共訪問權限設定為“關閉”,并且我真的不知道切換哪個開關以允許具有簽名 URL 的用戶能夠訪問資源。
這是 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
: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,
'Key': object_name},
ExpiresIn=expiration)
except ClientError as e:
logging.error(e)
return None
# The response contains the presigned URL
return response
UPDATE UPDATE - 由于這個問題還不夠清楚,而且我似乎對我的“寬松”語言采取了一些自由,讓我澄清一些事情。
1 - What am I actually trying to do? I want to keep my s3 bucket secure in such a way that only user's with presigned URL's generated by "me" can access whatever resource is there. 2 - When I ask if "my approach" is better or if there's any other approach what do I mean by that? I wanna know if there's a "native" / aws provided way of accessing the bucket without having to write a backend endpoint that'd fetch the resource and throw it back on the frontend. 3 - How do I measure one approach against another ? I think this one is quite obvious, you don't try to write an authentication flow from scratch if there's one provided by your framework*. This logic applies here too, if there's a way to access the objects that's listed by AWS then I probably shouldn't go about writing my own "hack"
uj5u.com熱心網友回復:
預簽名 URL 已通過。您可以阻止所有公共訪問,但仍然能夠生成簽名 URL 并將其提供給前端。我已經在我的問題中鏈接了官方檔案,這是我最終得到的最后一段代碼。
def create_presigned_url(bucket_name, bucket_key, expiration=3600, signature_version='s3v4'):
"""Generate a presigned URL for the S3 object
:param bucket_name: string
:param bucket_key: string
:param expiration: Time in seconds for the presigned URL to remain valid
:param signature_version: string
:return: Presigned URL as string. If error, returns None.
"""
s3_client = boto3.client('s3',
aws_access_key_id=settings.AWS_ACCESS_KEY_ID,
aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY,
config=Config(signature_version=signature_version),
region_name='us-east-1'
)
try:
response = s3_client.generate_presigned_url('get_object',
Params={'Bucket': bucket_name,
'Key': bucket_key},
ExpiresIn=expiration)
except ClientError as e:
logging.error(e)
return None
# The response contains the pre-signed URL
return response
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/313706.html
