使用Micronaut Java创建GCP存储桶时出现401未授权错误
核心根因
- 未复用Micronaut自动装配的凭证逻辑
代码中手动调用StorageOptions.newBuilder().setProjectId(xxx).build()构建客户端时,只会触发Google Cloud SDK的默认凭证链路,完全不会读取application.yml中配置的gcp.credentials.location路径下的密钥,直接导致Storage实例内部凭证为null,触发401未授权错误。 - 服务账号身份不匹配
classpath下密钥文件对应的服务账号为fetebirdstorage@fetebird.iam.gserviceaccount.com,但执行IAM权限绑定时,授权的是名称带横杠的fetebird-storage@fetebird.iam.gserviceaccount.com,二者并非同一个服务账号,即使凭证加载正常,也会因权限不足报错。 - 依赖引入缺失,无法触发框架自动装配
仅引入micronaut-gcp-common公共依赖,缺少Cloud Storage对应的Micronaut GCP starter依赖,框架不会自动完成凭证加载、Storage客户端Bean的装配流程。
修复步骤
- 补全GCP Cloud Storage对应的Micronaut依赖,构建文件中追加:
implementation("io.micronaut.gcp:micronaut-gcp-storage:2.0.2") - 对齐服务账号身份,给密钥文件对应的服务账号(
fetebirdstorage@fetebird.iam.gserviceaccount.com)绑定存储管理员角色,执行命令:gcloud projects add-iam-policy-binding --member=serviceAccount:fetebirdstorage@fetebird.iam.gserviceaccount.com --role=roles/storage.admin fetebird - 替换代码中手动构建Storage实例的逻辑,改为依赖注入获取框架自动装配的Storage Bean,框架会自动读取配置的classpath路径下的密钥完成认证:
@Inject Storage storage; public Observable<Void> createBucketWithStorageClassAndLocation() { StorageClass storageClass = StorageClass.COLDLINE; try { Bucket bucket = storage.create( BucketInfo.newBuilder(googleUploadObjectConfiguration.bucketName()) .setStorageClass(storageClass) .setLocation(googleUploadObjectConfiguration.locationName()) .build() ); LOG.info(String.format("Created bucket %s in %s with storage class %s", bucket.getName(), bucket.getLocation(), bucket.getStorageClass())); } catch (Exception ex) { LOG.error(ex.getMessage()); } return Observable.empty(); } - 无需手动配置
GOOGLE_APPLICATION_CREDENTIALS环境变量,Micronaut会自动读取application.yml中配置的gcp.credentials.location路径完成认证,启动时可通过调试日志确认凭证加载路径是否匹配预期。
内容的提问来源于stack exchange,提问作者San Jaisy
相关产品推荐
相关产品推荐

