You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Amazon S3预签名URL上传PDF遇SignatureDoesNotMatch错误

Amazon S3预签名URL上传PDF时SignatureDoesNotMatch错误排查

问题1:是否需要在元数据中传递文件哈希?

不需要强制传递文件哈希。S3预签名URL上传默认不要求在元数据中包含文件哈希,若需验证文件完整性,可添加Content-MD5请求头,但这不是必选项,缺失该字段不会直接引发签名不匹配错误。

问题2:如何修复SignatureDoesNotMatch错误?

从错误返回的CanonicalRequest可以看出,x-amz-meta-content-type头的值为空,这是导致签名不匹配的核心原因——你将标准HTTP头Content-Type错误地放入了自定义元数据中,SDK自动为其添加了x-amz-meta-前缀,但实际请求中该头没有对应值,导致签名计算的内容与实际请求不一致。

具体修复步骤:

  1. 修正Content-Type的设置方式
    Content-Type是标准HTTP头,不属于自定义元数据范畴,需通过PutObjectRequest的contentType方法单独设置,而非放入metadata参数中。修改后的代码如下:

    public static String createPresignedUrl(final String region, final String bucketName, final String keyName,
                final Map<String, String> metadata) {
        try (final S3Presigner presigner = S3Presigner.builder().region(Region.of(region)).build()) {
    
            // 从元数据中分离出Content-Type
            String contentType = metadata.remove("Content-Type");
            
            PutObjectRequest.Builder objectRequestBuilder = PutObjectRequest.builder()
                .bucket(bucketName)
                .key(keyName)
                .metadata(metadata);
            
            // 若存在Content-Type则设置为标准头
            if (contentType != null) {
                objectRequestBuilder.contentType(contentType);
            }
    
            PutObjectRequest objectRequest = objectRequestBuilder.build();
    
            PutObjectPresignRequest presignRequest = PutObjectPresignRequest.builder()
                .signatureDuration(Duration.ofMinutes(10)) // URL有效期10分钟
                .putObjectRequest(objectRequest)
                .build();
    
            PresignedPutObjectRequest presignedRequest = presigner.presignPutObject(presignRequest);
            String myURL = presignedRequest.url().toString();
            log.info("Presigned URL to upload a file to: [{}]", myURL);
            log.info("HTTP method: [{}]", presignedRequest.httpRequest().method());
    
            return presignedRequest.url().toExternalForm();
        }
    }
    
  2. 验证请求一致性
    修正后,标准的Content-Type会作为独立的签名头参与计算,不会生成空值的x-amz-meta-content-type头,确保签名计算的内容与实际请求完全匹配。

  3. 额外排查点

    • 确认生成预签名URL使用的AWS凭证(Access Key/Secret Key)有效,且拥有目标S3桶的PutObject权限
    • 确保上传请求使用PUT方法(与预签名URL指定的方法一致)
    • 检查请求时预签名URL未过期(当前设置为10分钟)
    • 禁止修改预签名URL中的任何参数(如签名、过期时间等)

内容的提问来源于stack exchange,提问作者Shubham

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 13:37:04