Amazon S3 预签名证书无效 URL

Invalid Certification with Amazon S3 Presigned URL

我正在尝试通过以下配置和代码使用预签名 url 从 S3 存储桶下载对象:

public void getDocumentFromPresignedUrl(final String presignedUrl, final String id) {
    
    PresignedUrlDownload transfer = null;
    
    try {
        
        File file = File.createTempFile(id, ".pdf");

        //errors out on this line
        transfer = getTransferMgr().download(new PresignedUrlDownloadRequest(new URL(presignedUrl)), file);
        transfer.waitForCompletion();
   }
}

通过以下配置:

private ClientConfiguration getClientConfiguration() {
    
    ClientConfiguration clientConfig = new ClientConfiguration();
    clientConfig.setProtocol(Protocol.HTTPS);
    
    return clientConfig;
    
}

public TransferManager getTransferMgr() {
    return TransferManagerBuilder.standard().withS3Client(getS3Client()).build();
}

public AmazonS3 getS3Client() {
    return AmazonS3ClientBuilder.standard().withRegion(region)
         .withClientConfiguration(getClientConfiguration()).build();
}

但是每次都会抛出如下错误:

com.amazonaws.SdkClientException: 
Unable to execute HTTP request: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target

我尝试了什么:

  1. 我试图从浏览器中的预签名 url 位置获取 AWS 证书,讨论 here

  2. 我尝试使用 Spring 提供的传统 RestTemplate,但没有成功

  3. AM 能够在 Postman 和我的浏览器中从 S3 检索对象,但不能通过我的 Spring 应用程序

如何规避此 sdkClientException 并获取他们的 S3 对象?

此问题的解决方案在于 cacerts。如果您 运行 使用代理(例如 Zscaler),则需要将证书添加到 /cacerts 文件中。

对于这个问题,我将 Zscaler 证书添加到错误的 JRE。因为我使用的是 SpringToolSuite,所以我需要将证书添加到 Spring 的 JRE,在我的例子中是:

keytool -import -alias Z_Root -keystore "C:\Program Files\sts-4.8.1.RELEASE\plugins\org.eclipse.justj.openjdk.hotspot.jre.full.win32.x86_64_1.v20201010-1246\jre\lib\security\cacerts" -storepass changeit -file "C:\Users\myUser\Downloads\MyZscalerCert.crt"

而不是典型的 %JAVA_HOME%/jre 路径。