方法调用以获得预先签名的URL给出不一致的结果(S3)

时间:2017-04-17 12:19:10

标签: java amazon-web-services amazon-s3 aws-sdk

我正在使用AmazonS3Client类的generatePresignedUrl方法来获取预签名的URL。但是,在与上载文件相同的会话中调用该方法时。它返回表单的URL:

https://mp-dev.downloads.XYZ.com.s3.ap-south-1.amazonaws.com/certificate/404/17_04_2017/XYZ/ITHLUaXYPnMmHEUbK9L21KBneJQy7oJ1jw.zip?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170417T090656Z&X-Amz-SignedHeaders=host&X-Amz-Expires=900&X-Amz-Credential=ASDFSFFGODQ%2F20170417%2Fap-south-1%2Fs3%2Faws4_request&X-Amz-Signature=9b2e112608c46cbeb16ff577b6e1321f889efsdfdsc850212251b231cb909d1942

但是当我重新运行我的API并使用相同的参数调用相同的方法时,我得到了表单的URL:

https://mp-dev.downloads.XYZ.com.s3.amazonaws.com/certificate/404/17_04_2017/XYZ/ITHLUaXYPnMmHEUbK9L21KBneJQy7oJ1jw.zip?AWSAccessKeyId=AKIAJFAFDTTISR4UHODQ&Expires=1492421420&Signature=CZuY1acATGUEEpoXN8aEQFXLX18%3D

第一个网址工作正常但第二个网址导致:

  

不支持您提供的授权机制。请   使用AWS4-HMAC-SHA256。

我尝试根据以下讨论更改配置以使用签名版本4:

The authorization mechanism you have provided is not supported. Please use AWS4-HMAC-SHA256

但是不起作用。问我是否需要任何其他信息。

生成网址的端点:

@SkipAuthentication
  @GET
  @Path("/xyz")
  public String download(@QueryParam("cer") String objectKey) {
    return testService.test(objectKey).toString();
  }

服务测试方法:

public URL test(String objectKey) {
    return awsDownloadService.generateDownloadUrl(objectKey, awsServer.getDownloadsBucketName());
  }

generateDownloadUrl方法如下:

  public URL generateDownloadUrl(String keyName, String bucketName) {
    LOG.info("generateDownloadUrl - {} {} {} {}>",accessKeyId, secretAccessKey, keyName, bucketName);
    BasicAWSCredentials awsCreds = new BasicAWSCredentials(accessKeyId, secretAccessKey);
    AmazonS3Client s3Client = new AmazonS3Client(awsCreds);

    Date expiration = new Date();
    long msec = expiration.getTime();
    msec += 1000 * 60 * 15; // 15 minutes.
    expiration.setTime(msec);
    GeneratePresignedUrlRequest generatePresignedUrlRequest = 
                  new GeneratePresignedUrlRequest(bucketName, keyName);
    generatePresignedUrlRequest.setMethod(HttpMethod.GET); // Default.
    generatePresignedUrlRequest.setExpiration(expiration);
    URL url = s3Client.generatePresignedUrl(generatePresignedUrlRequest);
    LOG.info("GeneratePreAuthenticatedUrl - url generated is <{}>",url);
    return url;
  }

当我使用upload方法上传文件,然后调用终点生成url时,它工作正常但是当我重新启动api并调用终点生成url时,会返回不同的url,如问题前面所述。 / p>

解决方案和新查询:

我已经解决了这个问题。显然,AmazonS3Client已被弃用。以这种方式使客户端始终如一地运作:

AmazonS3ClientBuilder builder = AmazonS3ClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(awsCreds));
    builder.setRegion(Regions.AP_SOUTH_1.getName());
    AmazonS3 s3client = builder.build();

然而,之前展示的行为AmazonS3Client有点奇怪。任何人都可以解释之前的行为吗?

1 个答案:

答案 0 :(得分:0)

显然,最新的SDK中不推荐使用AmazonS3Client类。以下列方式创建客户端可以解决问题,因为它还需要考虑区域,因此会附加正确的签名版本:

BasicAWSCredentials awsCreds = new BasicAWSCredentials(accessKeyId, secretAccessKey);
    AmazonS3ClientBuilder builder = AmazonS3ClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(awsCreds));
    builder.setRegion(regionName);
    AmazonS3 s3client = builder.build();