feat(storage): enhance AWS S3 client configuration for presigned URLs

- Updated the AWS S3 client initialization to enforce SigV4 for presigned URLs, ensuring consistent header signing behavior across S3-compatible providers.
- Introduced a dedicated configuration for the S3 client to manage addressing styles and signature versions more effectively.
This commit is contained in:
Harry
2026-01-30 17:34:20 +08:00
parent 3f5f893e6c
commit 40b58dfcde

View File

@@ -2,7 +2,7 @@ import logging
from collections.abc import Generator
import boto3
from botocore.client import Config
from botocore.client import BaseClient, Config
from botocore.exceptions import ClientError
from configs import dify_config
@@ -14,15 +14,34 @@ logger = logging.getLogger(__name__)
class AwsS3Storage(BaseStorage):
"""Implementation for Amazon Web Services S3 storage."""
client: BaseClient
def __init__(self):
super().__init__()
self.bucket_name = dify_config.S3_BUCKET_NAME
# NOTE:
# Some S3-compatible providers (e.g. MinIO) are strict about presigned request
# signature calculation. If the client sends a `Content-Type` header while the
# server generates a SigV2 presigned URL (or otherwise signs an empty Content-Type),
# the request may be rejected with 403 (signature mismatch).
#
# Enforce SigV4 for presigned URLs to avoid accidental SigV2 fallback and to keep
# header signing behavior consistent across providers.
s3_client_config = Config(
signature_version="s3v4",
s3={"addressing_style": dify_config.S3_ADDRESS_STYLE},
)
if dify_config.S3_USE_AWS_MANAGED_IAM:
logger.info("Using AWS managed IAM role for S3")
session = boto3.Session()
region_name = dify_config.S3_REGION
self.client = session.client(service_name="s3", region_name=region_name)
self.client = session.client(
service_name="s3",
region_name=region_name,
config=s3_client_config,
)
else:
logger.info("Using ak and sk for S3")
@@ -32,7 +51,7 @@ class AwsS3Storage(BaseStorage):
aws_access_key_id=dify_config.S3_ACCESS_KEY,
endpoint_url=dify_config.S3_ENDPOINT,
region_name=dify_config.S3_REGION,
config=Config(s3={"addressing_style": dify_config.S3_ADDRESS_STYLE}),
config=s3_client_config,
)
# create bucket
try: