GCP ADC模拟服务账号未被识别:spring-cloud-gcp-pubsub报错问题
impersonated_service_account类型不识别问题 问题场景
使用GCP应用默认凭据(ADC)进行服务账号模拟时,Spring Cloud GCP PubSub项目抛出如下异常:
Error reading credentials from stream, 'type' value 'impersonated_service_account' not recognized. Expecting 'authorized_user' or 'service_account'.
虽然代码层面确认impersonated_service_account类型是被支持的,但堆栈跟踪显示当前使用的是旧版依赖:
Caused by: java.io.IOException: Error reading credential file from location C:\Users\<my_user>\AppData\Roaming\gcloud\application_default_credentials.json: Error reading credentials from stream, 'type' value 'impersonated_service_account' not recognized. Expecting 'authorized_user' or 'service_account'. at com.google.auth.oauth2.DefaultCredentialsProvider.getDefaultCredentialsUnsynchronized(DefaultCredentialsProvider.java:186) ~[google-auth-library-oauth2-http-0.21.1.jar:na] at com.google.auth.oauth2.DefaultCredentialsProvider.getDefaultCredentials(DefaultCredentialsProvider.java:126) ~[google-auth-library-oauth2-http-0.21.1.jar:na] at com.google.auth.oauth2.GoogleCredentials.getApplicationDefault(GoogleCredentials.java:119) ~[google-auth-library-oauth2-http-0.21.1.jar:na] at com.google.auth.oauth2.GoogleCredentials.getApplicationDefault(GoogleCredentials.java:91) ~[google-auth-library-oauth2-http-0.21.1.jar:na] at com.google.api.gax.core.GoogleCredentialsProvider.getCredentials(GoogleCredentialsProvider.java:67) ~[gax-1.57.1.jar:1.57.1] at org.springframework.cloud.gcp.core.DefaultCredentialsProvider.getCredentials(DefaultCredentialsProvider.java:67) ~[spring-cloud-gcp-core-1.2.5.RELEASE.jar:1.2.5.RELEASE] at com.google.api.gax.rpc.ClientContext.create(ClientContext.java:136) ~[gax-1.57.1.jar:1.57.1] at com.google.cloud.pubsub.v1.stub.GrpcSubscriberStub.create(GrpcSubscriberStub.java:272) ~[google-cloud-pubsub-1.108.0.jar:1.108.0] at org.springframework.cloud.gcp.pubsub.support.DefaultSubscriberFactory.createSubscriberStub(DefaultSubscriberFactory.java:278) ~[spring-cloud-gcp-pubsub-1.2.5.RELEASE.jar:1.2.5.RELEASE]
原因分析
impersonated_service_account类型的凭据支持是在google-auth-library-java 1.0.0及以上版本才引入的,你当前依赖的0.21.1版本属于旧版,不支持该类型。而Spring Cloud GCP 1.2.5.RELEASE默认依赖的google-auth-library版本较低,导致无法识别模拟服务账号的凭据格式。
解决方案
1. 强制升级google-auth-library-oauth2-http版本
在项目依赖管理中指定更高版本的google-auth-library-oauth2-http(推荐1.19.0及以上稳定版),覆盖Spring Cloud GCP的默认依赖:
Maven示例:
<dependencyManagement> <dependencies> <dependency> <groupId>com.google.auth</groupId> <artifactId>google-auth-library-oauth2-http</artifactId> <version>1.19.0</version> </dependency> </dependencies> </dependencyManagement>
Gradle示例:
dependencies { implementation 'com.google.auth:google-auth-library-oauth2-http:1.19.0' }
2. 升级Spring Cloud GCP版本(推荐方案)
Spring Cloud GCP 2.0及以上版本已经依赖了支持impersonated_service_account的google-auth-library版本,升级整个Spring Cloud GCP依赖可以彻底解决版本兼容问题:
Maven示例:
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-gcp-dependencies</artifactId> <version>2.0.7.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
3. 验证凭据文件格式
确保你的application_default_credentials.json包含正确的模拟服务账号格式,示例如下:
{ "type": "impersonated_service_account", "source_credentials": { "type": "authorized_user", "client_id": "...", "client_secret": "...", "refresh_token": "..." }, "target_service_account": "your-target-service-account@project-id.iam.gserviceaccount.com", "delegates": [], "lifetime": "3600s" }
内容的提问来源于stack exchange,提问作者HendPro12

