生成预签名 URL,格式为:s3.amazonaws.com/bucket.name

Generate Presigned URL with format: s3.amazonaws.com/bucket.name

我正在生成预签名的 urls,但由于 *.s3.amazonaws 证书,它对于带句点和 SSL 的存储桶名称有问题,如下所述: http://shlomoswidler.com/2009/08/amazon-s3-gotcha-using-virtual-host.html

有没有办法生成具有以下格式的 urls?: http://s3.amazonaws.com/bucket.name/key

我在 API 中没有看到选项。我猜我可以通过重新排列 url 来做到 "manually",但如果没有必要,我宁愿避免黑客攻击。

根据 Michael 的回答,这里是我现在使用的代码:

public static URL bucketNameAfterS3Url(URL url) {

    int index = url.getHost().indexOf("s3");
    String host = url.getHost().substring(index);
    String bucket = url.getHost().substring(0, index - 1);
    URL toUse;
    try {
        toUse = new URL(url.getProtocol(), host, url.getPort(), '/' + bucket + url.getFile());
    } catch (MalformedURLException e) {
    }
    return toUse;
}

没有任何官方方法可以做到这一点,但字符串操作并不像看起来那么粗略,因为可能的模式是有限的。存储桶名称不能包含斜杠,查找其他元素非常安全。

一个重要的考虑因素是区域,以及它如何影响 URL 的有效组合。

考虑 "lolcat.jpg" 桶 "example-bucket"...

https://example-bucket.s3.amazonaws.com/lolcat.jpg
https://s3.amazonaws.com/example-bucket/lolcat.jpg

这两个 url 是等效的 仅当存储桶位于美国标准区域时

如果不是,顶部的可以工作,但底部的会 return 一条错误消息,告诉您您使用了错误的端点。

对于其他区域,您必须使用正确的区域端点。如果是 us-west-2,这实际上是:

https://s3-us-west-2.amazonaws.com/example-bucket/lolcat.jpg

因此,在转置 URL 中的元素之前,您必须知道存储桶的区域。

如果您使用的是签名版本 4,那么您已经知道该区域,因为生成签名需要它。使用签名版本 2,您甚至可以在 URL 之后重新排列存储桶名称的位置 签署 URL 而不会使签名无效,因为详细信息该算法。

S3 客户端允许您设置一个选项来配置它:

    // Configure the S3 client to generate urls with valid SSL certificates. With this setting we will get urls
    // like https://s3.amazonaws.com/bucket_name/... but if this is not set we will get urls like
    // https://bucket_name.s3.amazonaws.com/ which will cause the browser to complain about invalid SSL
    // certificates.
    s3Client.setS3ClientOptions(new S3ClientOptions().withPathStyleAccess(true));