我無法通過簽名URL將文件放入Google雲服務。當我嘗試從JS客戶端執行PUT時,得到:使用簽名URL時Google雲服務失敗
「SignatureDoesNotMatch ...我們計算的請求籤名與您提供的簽名不匹配。請檢查您的Google祕密密鑰和簽名方法。
當我嘗試使用CURL發佈文件時,出現同樣的錯誤。
捲曲命令我用的是:
#!/bin/bash
URL="https://storage.googleapis.com/..."
echo $URL
curl $URL -H "Content-Type: image/jpg" --upload-file b.jpg
我已經配置我打算數據發佈到基於文檔桶中,我已生成與密鑰服務帳戶,並且該鍵用於生成簽名的網址。
我註冊的請求的形式是:
PUT
image/jpg
1234567890
my-bucket/b.jpg
其中期滿和剷鬥的名稱被設置和計算。
我有以下Groovy代碼生成簽署的網址:
public String sign(PrivateKey key, String toSign) {
Signature signer = Signature.getInstance("SHA256withRSA");
signer.initSign(key);
signer.update(toSign.getBytes("UTF-8"));
byte[] rawSignature = signer.sign();
String s = new String(Base64.encodeBase64(rawSignature), "UTF-8");
return s;
}
public String signUrl(PrivateKey key, String clientId, String method, String md5, String contentType,
long expiration, String gcsPath) {
String toSign = "${method}\n${md5}\n${contentType}\n${expiration}\n${gcsPath}";
String signature = sign(key, toSign);
String url = java.net.URLEncoder.encode(signature);
return url;
}
public String generateSignedUrl(PrivateKey key, String clientId, String method, String md5, String contentType,
long expiration, String gcsPath) {
String canonicalizedResource = "/${gcsPath}";
String signature = signUrl(key, clientId, method, md5, contentType, expiration, canonicalizedResource);
String finalUrl = "https://storage.googleapis.com/${gcsPath}?GoogleAccessId=${clientId}&Expires=${expiration}&Signature=${signature}"
finalUrl
}
此代碼伴隨着下面通過單元測試擡起直出gsutils GitHub的項目(https://github.com/GoogleCloudPlatform/gsutil/blob/master/gslib/tests/test_signurl.py)的:
@Test
void thatWeCanSignAPutUrlCorrectly() {
String expected = """https://storage.googleapis.com/test/[email protected]&Expires=1391816302&Signature=A6QbgTA8cXZCtjy2xCr401bdi0e7zChTBQ6BX61L7AfytTGEQDMD%2BbvOQKjX7%2FsEh77cmzcSxOEKqTLUDbbkPgPqW3j8sGPSRX9VM58bgj1vt9yU8cRKoegFHXAqsATx2G5rc%2FvEliFp9UWMfVj5TaukqlBAVuzZWlyx0aQa9tCKXRtC9YcxORxG41RfiowA2kd8XBTQt4M9XTzpVyr5rVMzfr2LvtGf9UAJvlt8p6T6nThl2vy9%2FwBoPcMFaOWQcGTagwjyKWDcI1vQPIFQLGftAcv3QnGZxZTtg8pZW%2FIxRJrBhfFfcAc62hDKyaU2YssSMy%2FjUJynWx3TIiJjhg%3D%3D""";
long expiration = 1391816302;
String signedUrl = gsUtils.generateSignedUrl(privateKey, "[email protected]","PUT", "", "", expiration, "test/test.txt")
assertEquals(expected, signedUrl);
}
感謝您提供的任何見解,我一直在解決這個問題。
我想知道,如果您通過「gsutil signurl」命令直接生成簽名的URL,它是否仍然失敗? –
嗨布蘭登,非常感謝你的幫助!使用gsutils生成URL會產生不同的錯誤:'<?xml version ='1.0'encoding ='UTF-8'?>訪問被拒絕。 調用方沒有storage.objects.create訪問bucket my-bucket。 ' –
scipio
AccessDenied
嗨布蘭登,使服務帳戶成爲桶的「所有者」解決了這個問題。所以,基本上,我可以使用gsutil簽署url並通過curl發佈,這太棒了!我正在通過下面的建議,這是一點點。這太棒了! – scipio