使用签名网址上传到Google云端存储时面临的问题

问题描述:

我在应用引擎端点中创建signedURL,然后将其提供给客户端。但是,当客户端尝试使用标识的URL上传,云存储引发以下错误使用签名网址上传到Google云端存储时面临的问题

Access denied. Anonymous users does not have storage.objects.create access to bucket

App Engine的代码来生成标识的URL如下:

private String getSignedUrl() { 
String encodedUrl = null; 
String httpVerb = "PUT"; 
String contentMD5 = ""; 
String contentType = "image/rgb"; 

Calendar calendar = Calendar.getInstance(); 
calendar.add(Calendar.MINUTE, 10); 
long expiration = calendar.getTimeInMillis()/1000L; 
String canonicalizedExtensionHeaders = ""; 
String canonicalizedResource = 
    "/<bucket_name>/<folder_name>/"; 

String stringToSign = 
    httpVerb + "\n" + contentMD5 + "\n" + contentType + "\n" 
     + expiration + "\n" + canonicalizedExtensionHeaders 
     + canonicalizedResource; 

AppIdentityService service = 
    AppIdentityServiceFactory.getAppIdentityService(); 
String googleAccessId = service.getServiceAccountName(); 

String baseURL = 
    "http://storage.googleapis.com/<bucket_name>/<folder-name>/"; 
SigningResult signingResult = 
    service.signForApp(stringToSign.getBytes()); 
String encodedSignature = null; 
try { 
    encodedSignature = 
     URLEncoder.encode(
      new String(Base64.encodeBase64(
       signingResult.getSignature(), false), 
       "UTF-8"), "UTF-8").toString(); 
} catch (UnsupportedEncodingException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} 
encodedUrl = 
    baseURL + "?GoogleAccessId=" + googleAccessId + "&Expires=" 
     + expiration + "&Signature=" + encodedSignature; 

return encodedUrl; 
} 

,并获得后签名的URL,我正在使用cURL来测试上传。我使用以下命令来上传文件

curl -X PUT -H "Content-Type: multipart/form" -F [email protected]"<file_path>";type=image/rgb <signed_url> 

我已经在cURL中尝试了POST和PUT,结果相同。 我在这里错过了什么吗?

+0

我不知道这是不是问题,但一般情况下,您可能想要为HTTPS而不是HTTP签名URL。 –

+0

即使使用https并根据@Andrei建议删除文件夹名称后,我无法从客户端上传。 –

从内存写入这里,但我认为你需要提供对象名称。另外,您在baseURL中包含文件夹名称 - 只应包含存储桶名称。 “文件夹”名称是对象名称的一部分。

+0

我其实想要生成签名的URL,以便客户可以上传到GCS而无需使用Google帐户。因此,基本URL中没有对象名称。正如你所建议的,我已经从代码中的'canonicalizedResource'和'baseURL'中删除了文件夹名称。现在我正在观察以下错误响应'MissingSecurityHeader您的请求缺少必需的标题。

授权
' –

+0

您可以检查客户端以确定它正在发送URL查询参数吗?这听起来像是如果它一路剥离Signature参数会发生的事情。值得尝试的另一件事是给客户一个已知的好签名URL来查看它是否有效。 gsutil实用程序可以为您生成它们。 –

+0

@SudarshanMurthy:工作流程是这样的:要求用户选择要上传的文件,获取文件名称,从后端请求签名的URL,将此URL设置为文件上传表单,提交文件上传表单。 –

您也可以URL编码googleAccessIdencodedSignature因为在服务帐户电子邮件@符号和base64编码字符串可能被解码为服务器的空间+性格。