Google 云存储:401 未经授权的错误
Google Cloud Storage: 401 unauthorized error
我的目标是将文件从 cloudhub 上传到 GCP 存储桶,我使用的是服务帐户,我唯一的选择是使用 Json 密钥文件。
这是我所做的:
- 我已参考此 GCP information and this post 将文件上传到 GCP 云存储,我可以通过本地推送文件,但在 Cloudhub 中我无法将文件推送到存储桶。
我正在接收 401 unauthorized error
。
在两个 link 中都提到了在环境变量中设置 GOOGLE_APPLICATION_CREDENTIALS = "path-to-json-key"
的步骤。
当我尝试在本地传递绝对路径 (/Users/..json-key
) 时它起作用并且文件被上传到存储桶但是当我尝试在 cloudhub 运行时管理器中传递 ${app.home}/"json-key"
或 ${mule.home}/apps/${app.name}/"json-key"
作为值,它失败了。
该文件位于 src/main/resources
目录中,我正在使用 java class(如第 2 link 中所述调用静态)上传文件。在这方面需要一些指导。
我想到的另一种方法是,是否有可能以某种方式在 Java class 本身中使用此 json 密钥文件,而不是通过环境变量传递它?
如果以上两个选项都不起作用,还有其他方法可以使用服务帐户在 cloudhub 中部署应用程序吗? (APIkey 是我尝试过的一种方法,但它不会将 APIKey 限制到特定的桶)
Java Class
package com.mule.google.cloud.storage;
import com.google.cloud.storage.BlobId;
import com.google.cloud.storage.BlobInfo;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import static java.nio.charset.StandardCharsets.UTF_8;
public class Upload {
public static void uploadObject(String projectId, String bucketName, String objectName, String filePath)
throws IOException {
Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService();
BlobId blobId = BlobId.of(bucketName, objectName);
BlobInfo blobInfo = BlobInfo.newBuilder(blobId).build();
storage.create(blobInfo, filePath.getBytes(UTF_8));
}
}
错误日志
Message : Invocation of static Method 'uploadObject(java.lang.String,java.lang.String,java.lang.String,java.lang.String)' from Class 'com.mule.google.cloud.storage.Upload' with arguments [org.mule.runtime.core.internal.streaming.bytes.ManagedCursorStreamProvider arg0, org.mule.runtime.core.internal.streaming.bytes.ManagedCursorStreamProvider arg1, org.mule.runtime.core.internal.streaming.bytes.ManagedCursorStreamProvider arg2, org.mule.runtime.core.internal.streaming.bytes.ManagedCursorStreamProvider arg3] resulted in an error.
Expected arguments are [java.lang.String projectId, java.lang.String bucketName, java.lang.String objectName, java.lang.String filePath].
Cause: com.google.cloud.storage.StorageException - 401 Unauthorized
POST https://storage.googleapis.com/upload/storage/v1/b/"bucket-name"/o?projection=full&uploadType=multipart
Element : upload-logFile/processors/3 @ poc-gcs-test:poc-mule-gcs.xml:305 (Invoke static)
Element DSL : <java:invoke-static method="uploadObject(java.lang.String,java.lang.String,java.lang.String,java.lang.String)" doc:name="Invoke static" doc:id="3646e20f-0fef-4f57-84f8-d1ecc0f8afd5" class="com.mule.google.cloud.storage.Upload">
<java:args><![CDATA[
#[{
arg0: vars.projectId,
arg1: vars.bucketName,
arg2: vars.objectName,
arg3: vars.agg_msg default [],
}]
]]></java:args>
</java:invoke-static>
Error type : JAVA:INVOCATION
FlowStack : at upload-logFile(upload-logFile/processors/3 @ poc-gcs-test:poc-mule-gcs.xml:305 (Invoke static))
at consume-CustomerQ(consume-CustomerQ/processors/6 @ poc-gcs-test:poc-mule-gcs.xml:275 (Flow Reference upload-logFile))
Payload Type : org.mule.runtime.core.internal.streaming.bytes.ManagedCursorStreamProvider
--------------------------------------------------------------------------------
Root Exception stack trace:
com.google.api.client.googleapis.json.GoogleJsonResponseException: 401 Unauthorized
POST https://storage.googleapis.com/upload/storage/v1/b/"bucket-name"/o?projection=full&uploadType=multipart
注意 - 问题似乎不是密钥文件通过环境错误传递。 java class 或任何 package/dependency 无法通过具有该相对路径的环境访问它。
如果问题是无法在 CloudHub 中找到该文件,请尝试使用此方法引用它,如 KB article:
中所述
${mule.home}/apps/${app.name}/json-key
使用环境变量的方法在CloudHub上是行不通的,因为没有办法在设计上设置操作系统环境变量。您需要添加 manual authentication code as described in GCP documentation。您可以在 Java 方法中添加一个参数以接收上述流程中计算出的路径,并使用它来加载 Java.
中的密钥
示例:
var credential = GoogleCredential.FromFile(jsonPath);
var storage = StorageClient.Create(credential);
请注意,您不应使用 System.out.println()。它无法扩展并可能导致问题。使用 Log4j2 记录器从 Java 代码记录。
我的目标是将文件从 cloudhub 上传到 GCP 存储桶,我使用的是服务帐户,我唯一的选择是使用 Json 密钥文件。
这是我所做的:
- 我已参考此 GCP information and this post 将文件上传到 GCP 云存储,我可以通过本地推送文件,但在 Cloudhub 中我无法将文件推送到存储桶。
我正在接收 401 unauthorized error
。
在两个 link 中都提到了在环境变量中设置 GOOGLE_APPLICATION_CREDENTIALS = "path-to-json-key"
的步骤。
当我尝试在本地传递绝对路径 (/Users/..json-key
) 时它起作用并且文件被上传到存储桶但是当我尝试在 cloudhub 运行时管理器中传递 ${app.home}/"json-key"
或 ${mule.home}/apps/${app.name}/"json-key"
作为值,它失败了。
该文件位于 src/main/resources
目录中,我正在使用 java class(如第 2 link 中所述调用静态)上传文件。在这方面需要一些指导。
我想到的另一种方法是,是否有可能以某种方式在 Java class 本身中使用此 json 密钥文件,而不是通过环境变量传递它?
如果以上两个选项都不起作用,还有其他方法可以使用服务帐户在 cloudhub 中部署应用程序吗? (APIkey 是我尝试过的一种方法,但它不会将 APIKey 限制到特定的桶)
Java Class
package com.mule.google.cloud.storage;
import com.google.cloud.storage.BlobId;
import com.google.cloud.storage.BlobInfo;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import static java.nio.charset.StandardCharsets.UTF_8;
public class Upload {
public static void uploadObject(String projectId, String bucketName, String objectName, String filePath)
throws IOException {
Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService();
BlobId blobId = BlobId.of(bucketName, objectName);
BlobInfo blobInfo = BlobInfo.newBuilder(blobId).build();
storage.create(blobInfo, filePath.getBytes(UTF_8));
}
}
错误日志
Message : Invocation of static Method 'uploadObject(java.lang.String,java.lang.String,java.lang.String,java.lang.String)' from Class 'com.mule.google.cloud.storage.Upload' with arguments [org.mule.runtime.core.internal.streaming.bytes.ManagedCursorStreamProvider arg0, org.mule.runtime.core.internal.streaming.bytes.ManagedCursorStreamProvider arg1, org.mule.runtime.core.internal.streaming.bytes.ManagedCursorStreamProvider arg2, org.mule.runtime.core.internal.streaming.bytes.ManagedCursorStreamProvider arg3] resulted in an error.
Expected arguments are [java.lang.String projectId, java.lang.String bucketName, java.lang.String objectName, java.lang.String filePath].
Cause: com.google.cloud.storage.StorageException - 401 Unauthorized
POST https://storage.googleapis.com/upload/storage/v1/b/"bucket-name"/o?projection=full&uploadType=multipart
Element : upload-logFile/processors/3 @ poc-gcs-test:poc-mule-gcs.xml:305 (Invoke static)
Element DSL : <java:invoke-static method="uploadObject(java.lang.String,java.lang.String,java.lang.String,java.lang.String)" doc:name="Invoke static" doc:id="3646e20f-0fef-4f57-84f8-d1ecc0f8afd5" class="com.mule.google.cloud.storage.Upload">
<java:args><![CDATA[
#[{
arg0: vars.projectId,
arg1: vars.bucketName,
arg2: vars.objectName,
arg3: vars.agg_msg default [],
}]
]]></java:args>
</java:invoke-static>
Error type : JAVA:INVOCATION
FlowStack : at upload-logFile(upload-logFile/processors/3 @ poc-gcs-test:poc-mule-gcs.xml:305 (Invoke static))
at consume-CustomerQ(consume-CustomerQ/processors/6 @ poc-gcs-test:poc-mule-gcs.xml:275 (Flow Reference upload-logFile))
Payload Type : org.mule.runtime.core.internal.streaming.bytes.ManagedCursorStreamProvider
--------------------------------------------------------------------------------
Root Exception stack trace:
com.google.api.client.googleapis.json.GoogleJsonResponseException: 401 Unauthorized
POST https://storage.googleapis.com/upload/storage/v1/b/"bucket-name"/o?projection=full&uploadType=multipart
注意 - 问题似乎不是密钥文件通过环境错误传递。 java class 或任何 package/dependency 无法通过具有该相对路径的环境访问它。
如果问题是无法在 CloudHub 中找到该文件,请尝试使用此方法引用它,如 KB article:
中所述${mule.home}/apps/${app.name}/json-key
使用环境变量的方法在CloudHub上是行不通的,因为没有办法在设计上设置操作系统环境变量。您需要添加 manual authentication code as described in GCP documentation。您可以在 Java 方法中添加一个参数以接收上述流程中计算出的路径,并使用它来加载 Java.
中的密钥示例:
var credential = GoogleCredential.FromFile(jsonPath);
var storage = StorageClient.Create(credential);
请注意,您不应使用 System.out.println()。它无法扩展并可能导致问题。使用 Log4j2 记录器从 Java 代码记录。