1

jersey-client を使用して REST Call を作成しています。応答で SignatureDoesNotMatch エラーが発生します。GET Service を使用して Bucket 名を一覧表示しようとしましたが、 GET Bucket メソッドを使用して Bucket オブジェクトを一覧表示しようとしました。これが私のサンプルコードです。

ヒントや解決策はありますか?

public class restSample {

    private static final String HMAC_SHA1_ALGORITHM = "HmacSHA1";
    private static final String PROJECT_ID = "10XXXXXXXX478";

    public static String Base64Encoding()
            throws java.security.SignatureException, UnsupportedEncodingException {

          String access_id = "GOOGBAXXXXXXXXXXBI";
          String secret_key = URLEncoder.encode("pWTXXXXXXXXXXXXXXXRo85T+XXXXXXXXX3O","UTF-8");
          String bucket = "bucket_name";

          String version_header = "x-goog-api-version:1";
          String project_header = "x-goog-project-id:"+PROJECT_ID;
          String canonicalizedResources = "/"+bucket+"/";

          Calendar calendar = Calendar.getInstance();
          calendar.add(Calendar.MINUTE, 30);
          long expiration = calendar.getTimeInMillis();

         String stringToSign = URLEncoder.encode("GET\n\n\n"+expiration+"\n"+version_header+"\n"+project_header+"\n"+canonicalizedResources,"UTF-8");
         //String stringToSign = URLEncoder.encode("GET\n\n\n"+getdate()+"\n"+version_header+"\n"+project_header+"\n"+canonicalizedResources,"UTF-8");
         String authSignature="";
        try {

            SecretKeySpec signingKey = new SecretKeySpec(secret_key.getBytes(),HMAC_SHA1_ALGORITHM);

            Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);
            mac.init(signingKey);

            // compute the hmac on input data bytes
            byte[] rawHmac = mac.doFinal(stringToSign.getBytes("UTF-8"));

            // base64-encode the hmac
            authSignature = new String(Base64.encode(rawHmac));

        } catch (Exception e) {
            throw new SignatureException("Failed to generate HMAC : " + e.getMessage());
        }
        authSignature = (access_id +":"+ authSignature);
        return  authSignature;
    }

    public static void main(String[] args) {

        ClientConfig config = new DefaultClientConfig();
        Client client = Client.create(config);

        String authSignature = null;
        try {
            authSignature = "GOOG1 "+ Base64Encoding();
        } catch (SignatureException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        WebResource service = client.resource(getBaseURI());
        ClientResponse response = service.accept(MediaType.APPLICATION_XML)
                .header("Authorization",authSignature)
                .header("Date", getdate())
                .header("Content-Length", "0")
                .header("x-goog-api-version", "1")
                .header("x-goog-project-id", PROJECT_ID)
                .get(ClientResponse.class);

        System.out.println(response.getClientResponseStatus().getFamily());
        System.out.println("response1 :: " + response.getEntity(String.class));

    }

    private static URI getBaseURI() {
        String url = "https://bucket_name.storage.googleapis.com";
        return UriBuilder.fromUri(url).build();
    }
    private static String getdate(){
        SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z ", new Locale("US"));
         Calendar cal = Calendar.getInstance(new SimpleTimeZone(0, "GMT"));

         format.setCalendar(cal);
         return format.format(new Date());
    }
}

ありがとう!

4

1 に答える 1

1

署名する文字列が、署名する予定の文字列と一致することを確認してください。認証が失敗した場合、Google クラウド ストレージは HTTP 応答で署名するために予期される文字列を返します。

あなたの特定の例では、署名する文字列に と のversion_header両方を追加しているように見えます。project_headerこれらはCanonicalHeadersnorのリストにないCanonicalExtensionHeadersため、サーバーとは異なる文字列に署名しています。

ここでリストを確認できます: https://developers.google.com/storage/docs/reference/v1/developer-guidev1#authentication

于 2013-05-18T22:55:11.353 に答える