署名付きURL経由でファイルをGoogleクラウドサービスにプットできません。署名付きURLを使用するとGoogle Cloud Services putが失敗する
"SignatureDoesNotMatch ...私たちが計算したリクエストの署名が、指定した署名と一致しません.Googleの秘密鍵と署名方法を確認してください。
CURLを使用してファイルを投稿しようとすると、同じエラーが発生します。
私が使用curlコマンドは次のとおりです。私はドキュメントに基づいて、私はキーでサービスアカウントを生成しており、このキーがするために使用されるにデータをポストするつもりバケツを設定している
#!/bin/bash
URL="https://storage.googleapis.com/..."
echo $URL
curl $URL -H "Content-Type: image/jpg" --upload-file b.jpg
署名されたURLを生成します。
私は署名要求の形式は次のとおりです。
満了とバケット名を設定して計算されPUT
image/jpg
1234567890
my-bucket/b.jpg
。
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);
}
Iは、署名されたURLを生成するために、次のGroovyコードを有します
あなたが提供できる洞察力が何であれありがとう、私はこの問題にしばらくおかれました。
「gsutil signurl」コマンドで直接署名付きURLを生成すると、それでも失敗するのでしょうか? –
こんにちは、ブランドン、あなたの助けをありがとう! gsutilsでURLを生成すると、別のエラーが発生します: '<?xml version = '1.0' encoding = 'UTF-8'?>アクセスが拒否されました。 呼び出し元には、バケットmy-bucketへのstorage.objects.createアクセス権がありません。 –
scipio
AccessDenied
こんにちはBrandonさん、サービスアカウントをバケツの「所有者」にしてこの問題を解決しました。だから、基本的に、gsutilを使ってURLに署名し、カール経由で投稿することができます。これは素晴らしいことです!私はあなたの提案を以下にも取り組んでいます。それは少しずつです。これは最高です! – scipio