2013-04-22 150 views
1

我正在使用jersey-client进行REST调用。我收到SignatureDoesNotMatch错误的回应。 我试图列出使用GET服务的桶名称,也尝试使用GET桶方法列出Bucket对象。 这里是我的示例代码。Google Cloud Storage - JAVA REST API - 获取SignatureDoesNotMatch

任何提示或解决方案?

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()); 
    } 
} 

谢谢!

回答

1

确保您正在签名的字符串与要签署的预期字符串匹配。如果身份验证失败,Google云存储会返回预期的字符串以登录HTTP响应。

在您的特定示例中,您似乎将version_headerproject_header都添加到要签名的字符串中。这些不在CanonicalHeadersCanonicalExtensionHeaders的列表中,因此您正在签署与服务器不同的字符串。

您可以在这里查看列表:https://developers.google.com/storage/docs/reference/v1/developer-guidev1#authentication

相关问题