英文:
Getting a 403 Forbidden error when attempting to publish to GCP from a Spring Boot application
问题
I am attempting to utilize PubSub in my Spring Boot application to send messages to another service any time an item is updated or created. I have been simply trying to test the functionality of publishing a test message before setting it up for what I will actually need it for. However I am having some difficulty linking my application up to GCP. Every time I attempt to publish I receive a 403 Forbidden error as seen below.
Caused by: com.google.api.client.http.HttpResponseException: 403 Forbidden
POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/sa-test-app@test-project.iam.gserviceaccount.com:generateAccessToken
{
"error": {
"code": 403,
"message": "Permission 'iam.serviceAccounts.getAccessToken' denied on resource (or it may not exist).",
"errors": [
{
"message": "Permission 'iam.serviceAccounts.getAccessToken' denied on resource (or it may not exist).",
"domain": "global",
"reason": "forbidden"
}
],
"status": "PERMISSION_DENIED",
"details": [
{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "IAM_PERMISSION_DENIED",
"domain": "iam.googleapis.com",
"metadata": {
"permission": "iam.serviceAccounts.getAccessToken"
}
}
]
}
}
This error comes through about 10 minutes after I attempt the publish, when the request times out. I have tried this out using a service account and topic from my colleague's project that has been able to successfully publish and subscribe to GCP PubSub but I still receive the same error.
My code is nearly identical to my colleague's project with my publishing present in my @RestController as such:
@Autowired
PubSubTemplate pubSubTemplate;
@GetMapping("/postMessage")
public String publish(@RequestParam("topicName") String topicName,
@RequestParam("message") String message) {
pubSubTemplate.publish(topicName, message);
return "Messages published asynchronously; status unknown.";
}
And my subscription code in its own PubSubConfig file as such:
@Slf4j
@Configuration
public class PubSubConfiguration {
@Bean
public MessageChannel pubSubInputChannel() { return new PublishSubscribeChannel(); }
@Bean
public PubSubInboundChannelAdapter messageChannelAdapter(
@Qualifier("pubSubInputChannel") MessageChannel inputChannel,
PubSubTemplate pubSubTemplate) {
PubSubInboundChannelAdapter adapter =
new PubSubInboundChannelAdapter(pubSubTemplate, "test_pullsub");
adapter.setOutputChannel(inputChannel);
adapter.setAckMode(AckMode.MANUAL);
adapter.setPayloadType(String.class);
return adapter;
}
@ServiceActivator(inputChannel = "pubSubInputChannel")
public void messageReceiver(String payload,
@Header(GcpPubSubHeaders.ORIGINAL_MESSAGE) BasicAcknowledgeablePubsubMessage message) {
log.info("Message arrived via an inbound channel adapter from sub-one! Payload: " + payload);
message.ack();
}
}
I am triggering the publish event by sending a get request in Postman to the URL http://localhost:8080/cloc/postMessage?topicName=test-topic&message=Hello
with the application running locally.
I am able to reach a breakpoint set at pubSubTemplate.publish(topicName, message);
but after that the message is unable to go through.
I have been able to successfully publish a message via the Google CLI using the command gcloud pubsub topics publish test-topic --message="Hello World"
So I don't believe it is a permission issue with the service account.
If needed the imports I am using in my build.gradle
file are as such:
bomImport platform('io.pivotal.spring.cloud:spring-cloud-services-dependencies:2.4.1')
bomImport platform (group: 'com.google.cloud', name: 'spring-cloud-gcp-dependencies', version: '3.2.1')
implementation 'org.springframework.cloud:spring-cloud-gcp-starter-pubsub:1.2.5.RELEASE'
implementation platform('com.google.cloud:libraries-bom:26.10.0')
implementation 'com.google.cloud:google-cloud-pubsub'
Any help would be greatly appreciated.
英文:
I am attempting to utilize PubSub in my Spring Boot application to send messages to another service any time an item is updated or created. I have been simply trying to test the functionality of publishing a test message before setting it up for what I will actually need it for. However I am having some difficulty linking my application up to GCP. Every time I attempt to publish I receive a 403 Forbidden error as seen below.
Caused by: com.google.api.client.http.HttpResponseException: 403 Forbidden
POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/sa-test-app@test-project.iam.gserviceaccount.com:generateAccessToken
{
"error": {
"code": 403,
"message": "Permission 'iam.serviceAccounts.getAccessToken' denied on resource (or it may not exist).",
"errors": [
{
"message": "Permission 'iam.serviceAccounts.getAccessToken' denied on resource (or it may not exist).",
"domain": "global",
"reason": "forbidden"
}
],
"status": "PERMISSION_DENIED",
"details": [
{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "IAM_PERMISSION_DENIED",
"domain": "iam.googleapis.com",
"metadata": {
"permission": "iam.serviceAccounts.getAccessToken"
}
}
]
}
}
This error comes through about 10 minutes after I attempt the publish, when the request times out. I have tried this out using a service account and topic from my colleague's project that has been able to successfully publish and subscribe to GCP PubSub but I still receive the same error.
My code is nearly identical to my colleague's project with my publishing present in my @RestController as such:
@Autowired
PubSubTemplate pubSubTemplate;
@GetMapping("/postMessage")
public String publish(@RequestParam("topicName") String topicName,
@RequestParam("message") String message) {
pubSubTemplate.publish(topicName, message);
return "Messages published asynchronously; status unknown.";
}
And my subscription code in it's own PubSubConfig file as such:
@Slf4j
@Configuration
public class PubSubConfiguration {
@Bean
public MessageChannel pubSubInputChannel() { return new PublishSubscribeChannel(); }
@Bean
public PubSubInboundChannelAdapter messageChannelAdapter(
@Qualifier("pubSubInputChannel") MessageChannel inputChannel,
PubSubTemplate pubSubTemplate) {
PubSubInboundChannelAdapter adapter =
new PubSubInboundChannelAdapter(pubSubTemplate, "test_pullsub");
adapter.setOutputChannel(inputChannel);
adapter.setAckMode(AckMode.MANUAL);
adapter.setPayloadType(String.class);
return adapter;
}
@ServiceActivator(inputChannel = "pubSubInputChannel")
public void messageReceiver(String payload,
@Header(GcpPubSubHeaders.ORIGINAL_MESSAGE) BasicAcknowledgeablePubsubMessage message) {
log.info("Message arrived via an inbound channel adapter from sub-one! Payload: " + payload);
message.ack();
}
}
I am triggering the publish event by sending a get request in Postman to the URL http://localhost:8080/cloc/postMessage?topicName=test-topic&message=Hello
with the application running locally.
I am able to reach a breakpoint set at pubSubTemplate.publish(topicName, message);
but after that the message is unable to go through.
I have been able to successfully publish a message via the Google CLI using the command
gcloud pubsub topics publish test-topic --message="Hello World"
So I don't believe it is a permission issue with the service account.
If needed the imports I am using in my build.gradle
file are as such:
bomImport platform('io.pivotal.spring.cloud:spring-cloud-services-dependencies:2.4.1')
bomImport platform (group: 'com.google.cloud', name: 'spring-cloud-gcp-dependencies', version: '3.2.1')
implementation 'org.springframework.cloud:spring-cloud-gcp-starter-pubsub:1.2.5.RELEASE'
implementation platform('com.google.cloud:libraries-bom:26.10.0')
implementation 'com.google.cloud:google-cloud-pubsub'
Any help would be greatly appreciated.
答案1
得分: 1
问题是您缺少iam.serviceAccounts.getAccessToken
权限。
将IAM角色roles/iam.serviceAccountTokenCreator
(服务帐号令牌创建器)添加到接收此错误的服务帐号。
英文:
The problem is that you are missing the permission iam.serviceAccounts.getAccessToken
.
Add the IAM roles/iam.serviceAccountTokenCreator
(Service Account Token Creator) to the service account receiving this error.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论