即使我在这里找到了类似的问题:
这不会导致解决我的问题。
我正在本地验证Google Storage默认服务帐户,因此可以轻松读取存储桶对象,如下所示:
private val storage: Storage = StorageOptions
.newBuilder()
.setProjectId(projectId)
.build()
.service
fun read() {
val blob = storage
.get(BlobId.of(bucket, object))
println(String(blob.getContent()))
}
但是,当我尝试使用以下方法生成签名的上传网址时:
fun uploadUrl(objectName: String): String = storage
.signUrl(
BlobInfo.newBuilder(BlobId.of(bucketName, objectName)).build(),
15,
TimeUnit.MINUTES,
Storage.SignUrlOption.httpMethod(HttpMethod.PUT),
Storage.SignUrlOption.withExtHeaders(mapOf("Content-Type" to "application/octet-stream")),
Storage.SignUrlOption.withV4Signature()
)
.toString()
我越来越signing key not provided
。
我发现很难识别出我实际上所缺少的东西。我已gcloud auth application-default login
通过owner
用户身份验证,通常可以执行任何gcloud任务。这里有什么区别?
要签名,您需要一个私钥。拥有用户凭证就不能了,因为您的环境中只有一个刷新令牌。但是,在服务帐户密钥文件中,您具有私钥。您可以下载并使用它,但出于安全原因,我不喜欢它。
我写了一篇文章,发现了一个Python解决方法。我用Java构建了一个类似的技巧(对不起,我不是kotlin开发者!但是我敢肯定,每个人都可以转换!)。
Storage storage = StorageOptions.getDefaultInstance().getService();
Credentials credentialsToSIgn = storage.getOptions().getCredentials();
if (credentialsToSIgn instanceof UserCredentials) {
credentialsToSIgn = ImpersonatedCredentials.create(
(GoogleCredentials) credentialsToSIgn,
"SERVICE_ACCOUNT_EMAIL",
Collections.EMPTY_LIST,
Collections.EMPTY_LIST,
3600);
}
System.out.println(
storage.signUrl(
BlobInfo.newBuilder(BlobId.of(bucketName, objectName)).build(),
15,
TimeUnit.MINUTES,
Storage.SignUrlOption.httpMethod(HttpMethod.PUT),
Storage.SignUrlOption.withExtHeaders(mapOf("Content-Type" to "application/octet-stream")),
Storage.SignUrlOption.withV4Signature()
Storage.SignUrlOption.signWith((ServiceAccountSigner) credentialsToSIgn)
)
);
ImpersonatedCredentials仅在此处使用class中的sign方法。如我的文章中所述,此sign方法使用IAMUtils.sign方法,该方法调用服务帐户凭据API。
这不是一个不错的技巧,但可以。您可以在参数中放入服务帐户电子邮件,并在本地环境之外忽略它,以确保不会在其他地方执行错误的操作。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句