Spring Boot调用GCP Storage API报匿名用户无storage.objects.get权限如何解决
问题根因
你在application.properties中配置的spring.cloud.gcp.credentials.location仅对Spring Cloud GCP官方封装的客户端组件生效,你当前直接使用Unirest发送原生HTTP请求,没有自动携带服务账号的认证凭证,Google服务端识别为匿名访问,因此触发权限错误。
解决方案
方案1:使用Spring Cloud GCP官方Storage客户端(推荐)
该方式会自动加载你配置的凭证,无需手动处理认证逻辑,稳定性更高:
- 首先确认项目已引入Spring Cloud GCP Storage依赖,Maven示例:
<dependency> <groupId>com.google.cloud</groupId> <artifactId>spring-cloud-gcp-starter-storage</artifactId> </dependency>
- 改造你的业务代码,直接注入官方
Storage客户端调用接口:
import com.google.cloud.storage.Blob; import com.google.cloud.storage.Storage; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component("GetObjFromGCP") class GetObjFromGCP{ @Autowired private Storage storage; public void readFromFile() { Blob blob = storage.get("sagessapp_test", "apache camel notes.txt"); String content = new String(blob.getContent()); System.out.println(content); } }
方案2:手动为Unirest请求添加认证头
如果必须使用Unirest发送原生请求,需要手动获取服务账号的访问令牌添加到请求头:
import com.google.auth.oauth2.GoogleCredentials; import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.Unirest; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.Resource; import org.springframework.stereotype.Component; import java.util.Collections; @Component("GetObjFromGCP") class GetObjFromGCP{ @Value("${spring.cloud.gcp.credentials.location}") private Resource gcpCredentials; public void readFromFile() throws Exception{ // 加载凭证获取访问令牌 GoogleCredentials credentials = GoogleCredentials.fromStream(gcpCredentials.getInputStream()) .createScoped(Collections.singletonList("https://www.googleapis.com/auth/devstorage.read_only")); credentials.refreshIfExpired(); String accessToken = credentials.getAccessToken().getTokenValue(); HttpResponse<String> jsonResponse = Unirest.get("https://storage.googleapis.com/storage/v1/b/sagessapp_test/o/apache%20camel%20notes.txt?alt=media") .header("accept", "application/json") .header("Authorization", "Bearer " + accessToken) .asString(); System.out.println(jsonResponse.getBody()); } }
额外排查项
- 确认你的服务账号已被授予对应存储桶的
roles/storage.objectViewer(存储对象查看者)权限 - 确认
classpath:/gcp-credentials.json文件存在且内容为正确的服务账号密钥文件
内容的提问来源于stack exchange,提问作者Jenny
相关产品推荐
相关产品推荐

