繁体   English   中英

使用 IamCredentialsClient 对 Blob 进行签名时的 INVALID_ARGUMENT 响应

[英]INVALID_ARGUMENT response when signingBlob using IamCredentialsClient

我正在关注这个关于如何手动签名 url的谷歌指南,因为我需要创建一个签名的 URL 以让其他用户上传文件而无需手动验证,同时我设法遵循python 示例中显示的所有步骤,我的 java 代码总是收到io.grpc.StatusRuntimeException: INVALID_ARGUMENT: Request contains an invalid argument

我正在疯狂地试图找出问题所在,但我不确定我是否做得正确。

我用于signBlob的依赖项是google-cloud-iamcredentials 有什么我错过的吗?

在这里你可以检查代码

try (IamCredentialsClient iamCredentialsClient = IamCredentialsClient.create()){
        final LocalDateTime currentTime = LocalDateTime.now();
        final String completeTimeStamp = currentTime.format(DateTimeFormatter.ofPattern("yyyyMMdd HHmmss"))
                .replace(" ", "T") + 'Z';
        final String pathToResource = "/" + filename;
        final String credentialScope = currentTime.format(DateTimeFormatter.BASIC_ISO_DATE) + "/eu/storage/goog4_request";
        String credential = clientEmail + '/' + credentialScope;
        credential = credential.replace("@", "%40");
        credential = credential.replace("/", "%2F");
        final String canonicalHeader = "host:" + bucketName + ".storage.googleapis.com\n";
        final String signedHeader = "host";
        final String canonicalQueryString =
                "X-Goog-Algorithm=GOOG4-RSA-SHA256&" +
                        "X-Goog-Credential=" + credential + '&' +
                        "X-Goog-Date=" + completeTimeStamp + '&' +
                        "X-Goog-Expires=" + expiration + '&' +
                        "X-Goog-SignedHeaders=" + signedHeader;
        final String canonicalRequest =
                "PUT" + '\n' +
                pathToResource + '\n' +
                canonicalQueryString + '\n' +
                canonicalHeader + '\n' +
                signedHeader + '\n' +
                "UNSIGNED-PAYLOAD";
        final String hashedCanonicalRequest =
                DigestUtils.sha256Hex(canonicalRequest.getBytes(StandardCharsets.UTF_8));
        final String stringToSign = "GOOG4-RSA-SHA256" + '\n' +
                completeTimeStamp + '\n' +
                credentialScope + '\n' +
                hashedCanonicalRequest;
        final String signature = iamCredentialsClient.signBlobCallable()
                .call(
                        SignBlobRequest.newBuilder()
                                .setName(ServiceAccountName.of(projectId, clientEmail).toString())
                                .addAllDelegates(new ArrayList<>())
                                .setPayload(ByteString.copyFrom(stringToSign.getBytes(StandardCharsets.UTF_8)))
                                .build()
                ).toString();
        return String.format(CLOUD_URL, pathToResource,
                canonicalQueryString, "&X-Goog-Signature=".concat(signature));

经过长时间的调试和更长的时间从这个问题中解脱出来后,我才发现我的问题。

根据这个资源https://cloud.google.com/iam/docs/reference/credentials/rest/v1/projects.serviceAccounts/signBlob ,原来我创建了错误的ServiceAccountName.of

您可以在参数部分下看到此评论

必需的。 为其请求凭据的服务帐户的资源名称,格式如下:projects/-/serviceAccounts/{ACCOUNT_EMAIL_OR_UNIQUEID}。 - 通配符是必需的; 用项目 ID 替换它是无效的。

这意味着我的代码没有以正确的格式构造此字段,我将ServiceAccountName.of(projectId, clientEmail).toString()更改为ServiceAccountName.of("-", clientEmail).toString()并且它起作用了!

我把这个作为我问题的答案,以防将来有人遇到这个确切的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM