2

サービス アカウントが POST オブジェクトをバケット リクエストに送信するための適切な構文とフォーマットを教えてくれる人がいるかどうか疑問に思っています。HttpComponents ライブラリを使用してプログラムで試しています。GoogleCredential からトークンを取得できましたが、POST リクエストを作成するたびに次のようになります。

HTTP/1.1 403 禁止

<?xml version='1.0' encoding='UTF-8'?><Error><Code>AccessDenied</Code><Message>Access denied.</Message><Details>バケット名</Details></Error>

リクエスト メソッドを説明しているGoogle のドキュメントには、html フォームを使用した投稿について言及されていますが、それが仕事を成し遂げる唯一の方法を示唆していないことを願っています。HttpComponents にはUrlEncodedFormEntityを使用して明示的にフォーム データを作成する方法があることは知っていますが、マルチパート データはサポートしていません。これが、MultipartEntity クラスを使用した理由です。私のコードは以下の通りです:

MultipartEntity entity = new MultipartEntity( HttpMultipartMode.BROWSER_COMPATIBLE );
String token = credential.getAccessToken();
entity.addPart("Authorization", new StringBody("OAuth " + token));
String date = formatDate(new Date());
entity.addPart("Date", new StringBody(date));
entity.addPart("Content-Type", new StringBody("multipart/form-data"));
entity.addPart("bucket", new StringBody(bucket));
entity.addPart("key", new StringBody("fileName"));
entity.addPart("success_action_redirect", new StringBody("/storage"));
File uploadFile = new File("pathToFile");
FileBody fileBody = new FileBody(uploadFile, "text/xml");
entity.addPart("file", fileBody);
httppost.setEntity(entity);
System.out.println("Posting URI = "+httppost.toString());
HttpResponse response = client.execute(httppost);
HttpEntity resp_entity = response.getEntity();

前述したように、私は実際のトークンを取得できたので、適切に認証されていないのではなく、リクエストをどのように作成したかに問題があると確信しています。

次の点に注意してください。

  1. これはサービス アカウントによって実行されています。
  2. つまり、読み取り/書き込みアクセス権があることを意味します

読んでくれてありがとう。助けてくれてありがとう!

4

1 に答える 1

2

PUT でのみ機能する OAuth アクセス トークンと、POST でのみ機能するフォーム フィールドを使用していることを考えると、メソッドPUTとメソッドを混同しているようです。POST

オブジェクトをアップロードする最も簡単な方法は、次のようなものを使用することです。

HttpPut put = new HttpPut("https://storage.googleapis.com/" + BUCKET + "/" + OBJECT);
put.addHeader("Authorization", "Bearer " + credential.getAccessToken());
put.setEntity(new StringEntity("object data"));
client.execute(put);

PUTを使用してオブジェクトをアップロードするために使用できる署名付き HTML フォームを作成することも可能ですが、単に を使用するよりも複雑ですPOST。フォームには、次のような署名済みのポリシー ドキュメントが必要です。

PolicyDocument = {"expiration": "2010-06-16T11:11:11Z",
 "conditions": [
   ["starts-with", "$key", "" ],
   {"acl": "bucket-owner-read" },
   {"bucket": "travel-maps"},
   {"success_action_redirect": "http://www.example.com/success_notification.html" },
   ["eq", "$Content-Type", "image/jpeg" ],
   ["content-length-range", 0, 1000000]
  ]
}
Policy = Base_64_Encoding_Of(PolicyDocument)
MessageDigest = Sha256_With_RSA(SecretKey, Policy)
Signature = Base64_Encoding_Of(MessageDigest)

これにより、次の HTML が生成されます。

<form action="http://travel-maps.storage.googleapis.com" method="post" enctype="multipart/form-data">
<input type="text" name="key" value="">
<input type="hidden" name="bucket" value="travel-maps">
<input type="hidden" name="Content-Type" value="image/jpeg">
<input type="hidden" name="GoogleAccessId" value="1234567890123@developer.gserviceaccount.com">
<input type="hidden" name="acl" value="bucket-owner-read">
<input type="hidden" name="success_action_redirect" value="http://www.example.com/success_notification.html">
<input type="hidden" name="policy" value="ajUJTm9jAHADNmF0aW9uIjogIjIwMTAtMDYtMTZUMTSAMPLEE6MTE6MTFaIiwNCSAMPLEiAgWyJzdGFydSAMPLEAiaHR0cDovL3maWNhSAMPLEIiB9LASAMPLEWN0aW9uX3JlZGlyZW">
<input type="hidden" name="signature" value="BSAMPLEaASAMPLE6SAMPLE+SAMPPLEqSAMPLEPSAMPLE+SAMPLEgSAMPLEzCPlgWREeF7oPGowkeKk7J4WApzkzxERdOQmAdrvshKSzUHg8Jqp1lw9tbiJfE2ExdOOIoJVmGLoDeAGnfzCd4fTsWcLbal9sFpqXsQI8IQi1493mw=">

<input name="file" type="file">
<input type="submit" value="Upload">
</form>

ポリシー ドキュメントで指定された条件に一致するポリシー フィールドと署名フィールド、およびその他の非表示フィールドに注意してください。具体的bucket == travel-mapsにはacl == bucket-owner-read、 など

于 2012-12-10T17:00:35.387 に答える