创建签名URL以将对象放入Google Storage

问题描述 投票:1回答:2

我正在努力创建签名网址以将文件上传到Google存储空间。首先,我使用JSON密钥获取私钥和​​clientId:

AuthCredentials.ServiceAccountAuthCredentials serviceAccountAuthCredentials = AuthCredentials.ServiceAccountAuthCredentials.createForJson(json_resource.getInputStream());
PrivateKey key = serviceAccountAuthCredentials.credentials().getPrivateKey();
Signature signer = Signature.getInstance("SHA256withRSA");
signer.initSign(key);

之后,创建要签名的字符串:

String upload_uri = "PUT\n\n" + expiration +
                "\n/" + bucketName + "/" + folderPath + "/" + fileName;

然后签署字符串:

signer.update(stringToSign.getBytes("UTF-8"));
byte[] rawSignature = signer.sign();
String signature = new String(Base64.encodeBase64(rawSignature, false), "UTF-8");

然后使用签名字符串组成URL:

final String clientId = serviceAccountAuthCredentials.account();
String url = "http://storage.googleapis.com/" + 
             bucketName + "/" + folderPath + "/" + fileName +
             "?GoogleAccessId=" + clientId +
             "&Expires=" + expiration +
             "&Signature=" + URLEncoder.encode(signature, "UTF-8");

使用此URL我收到错误:

SignatureDoesNotMatch我们计算的请求签名与您提供的签名不匹配。检查您的Google密钥和签名方法。获取1485340222074 / bucketName / fileName

java google-app-engine google-cloud-storage google-cloud-platform
2个回答
2
投票

您好,请查看我方的以下工作代码。我觉得你缺少一些参数作为get或token:`

    Calendar calendar = new GregorianCalendar();
            Long lExpireDate = Long.valueOf(calendar.getTime().getTime() + 7*86400000);//7 days validity
            String strExpireDate = fromDateLongtoStringISO8601(lExpireDate);

            String HTTP_Verb = "GET";
            String Content_MD5 = "";
            String Content_Type = "";//"image/jpeg";
            String Expiration = String.valueOf(lExpireDate/1000);
            String Canonicalized_Resource = "/"+bucketName+"/"+objectName;
            String StringToSign = HTTP_Verb + "\n" +
                    Content_MD5 + "\n" +
                    Content_Type + "\n" +
                    Expiration + "\n" +
                    Canonicalized_Resource;


            byte[] blob = StringToSign.getBytes();
            String BASE_URL = "https://storage.googleapis.com"+Canonicalized_Resource;

            ArrayList<String> scopes = new ArrayList<>();
            scopes.add(SQLAdminScopes.CLOUD_PLATFORM);
            appIdentity = AppIdentityServiceFactory.getAppIdentityService();
            AppIdentityService.GetAccessTokenResult accessToken = appIdentity.getAccessToken(scopes);

            AppIdentityService.SigningResult result = appIdentity.signForApp(blob);
            byte[] signatureByte = result.getSignature();
            String urlEncoded = com.google.api.client.util.Base64.encodeBase64String(signatureByte);
            String strURLBase64Encoded = URLEncoder.encode(urlEncoded);

            String GOOGLE_ACCESS_STORAGE_ID = appIdentity.getServiceAccountName();
            //GOOGLE_ACCESS_STORAGE_ID contains the email form of the client ID.

            String concatenatedURL = BASE_URL + "?GoogleAccessId=" + GOOGLE_ACCESS_STORAGE_ID
                    + "&Expires=" + strExpireDate
                    + "&access_token=" + URLEncoder.encode(accessToken.getAccessToken())
                    + "&Signature=" + strURLBase64Encoded;
            entity.setProperty(Media.URLD, concatenatedURL);

0
投票

我发现我必须在StringToSign中设置内容类型才能使PUT工作。在设置内容类型之前,我收到的是您收到的相同错误消息。

© www.soinside.com 2019 - 2024. All rights reserved.