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

Java 方法调用以获取给出不一致结果的预签名URL(S3),java,amazon-web-services,amazon-s3,aws-sdk,Java,Amazon Web Services,Amazon S3,Aws Sdk,我正在使用AmazonS3Client类的GeneratePressignedUrl方法来获得一个预签名的URL。但是,当在与文件上载相同的会话中调用该方法时。它返回表单的url: 但是,当我重新运行API并使用相同的参数调用相同的方法时,我会得到表单的url: 第一个Url工作正常,但第二个Url会导致: 不支持您提供的授权机制。请 使用AWS4-HMAC-SHA256 我已尝试根据以下讨论更改配置以使用签名版本4: 但是不起作用。询问我是否需要任何其他信息 要生成url的端点: @Sk

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

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

第一个Url工作正常,但第二个Url会导致:

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

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

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

要生成url的端点:

@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;
  }

尽管如此,之前展示的AmazonS3Client的行为还是有点奇怪。有人能解释一下之前的行为吗?

显然,
AmazonS3Client
类在最新的SDK中已被弃用。以以下方式创建客户端解决了问题,因为它还考虑了区域,因此附加了正确的签名版本:

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

您是否为两个连接指定了相同的区域?签名v4在较新的区域中是强制的。我没有为任何连接指定区域。正如我所说的,有一种方法可以获取凭据、bucket名称和密钥并调用generatePressignedUrl,但对于相同的参数,结果不同。有趣!你能提供一些最小的代码来重现这种情况吗?如果是,请将其插入您的问题。我已经提供了代码。生成不同URL的代码与生成相同URL的代码在哪里?另外,请只显示足够的代码来重现这种情况——不需要提供上传文件的代码,因为这与生成预签名URL无关。
BasicAWSCredentials awsCreds = new BasicAWSCredentials(accessKeyId, secretAccessKey);
    AmazonS3ClientBuilder builder = AmazonS3ClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(awsCreds));
    builder.setRegion(regionName);
    AmazonS3 s3client = builder.build();