AWS Lambda为含空格的S3对象打标签时遇403权限错误
解决AWS Lambda处理带空格S3对象时的AccessDenied错误
问题根源
S3触发Lambda时,事件中传递的对象键(s3.object.key)是URL编码后的格式,空格会被转换为+或%20。直接使用这个编码后的键调用put_object_tagging接口时,S3会尝试匹配编码后的键对应的对象,而实际存储的对象键是带空格的原始格式,这会导致权限校验失败(即使IAM权限配置正确)。
解决方案
在代码中对获取到的s3_key进行URL解码,使用Python的urllib.parse.unquote方法恢复原始的对象键格式。
修改后的代码
import json import logging import boto3 from botocore.exceptions import ClientError from urllib.parse import unquote # 新增URL解码工具导入 # Configure logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger() # Create an S3 client s3 = boto3.client('s3') def lambda_handler(event, context): # Log the event received logger.info(f"Received event: {json.dumps(event)}") try: # Iterate through each record in the event for record in event["Records"]: s3_bucket = record["s3"]["bucket"]["name"] # 对URL编码的对象键进行解码,还原空格等特殊字符 s3_key = unquote(record["s3"]["object"]["key"]) # Log bucket and key information logger.info(f"Processing object {s3_key} in bucket {s3_bucket}") # Define the tag set tags = { "TagSet": [ {"Key": "SomeKey", "Value": "SomeValue"} ] } # Log the tags being applied logger.info(f"Applying tags to object: {tags}") try: # Add tags to the object response = s3.put_object_tagging( Bucket=s3_bucket, Key=s3_key, Tagging=tags ) # Log the request ID from the response metadata request_id = response.get('ResponseMetadata', {}).get('RequestId', 'N/A') logger.info(f"Successfully tagged object {s3_key} in bucket {s3_bucket} with tags: {tags}. S3 request ID: {request_id}") except ClientError as e: # Log any exceptions from the put_object_tagging call logger.error(f"Error tagging object {s3_key} in bucket {s3_bucket}: {e.response['Error']['Message']}") if e.response["Error"]["Code"] == "AccessDenied": logger.error("Access Denied. Check if the Lambda function's role has the necessary permissions.") # Optionally raise the exception if you want to stop processing further records raise # Return a success response return { "statusCode": 200, "body": json.dumps("S3 object tagged!") } except Exception as e: # Log any exceptions logger.error(f"Error processing event: {str(e)}") # Raise the exception to allow Lambda to handle it raise
额外验证点
- 确认Lambda角色的IAM权限包含
s3:PutObjectTagging动作,且资源范围覆盖目标桶的所有对象(例如arn:aws:s3:::example/*)。 - 检查S3桶是否有桶策略限制了带空格对象的标签操作,确保策略允许Lambda角色的访问。
内容的提问来源于stack exchange,提问作者Jeffrey Demuth
相关产品推荐
相关产品推荐

