J'ai une application de démarrage de printemps qui communique avec S3 et SQS. Cela a fonctionné bien en utilisant des clés et des secrets AWS secrets, mais j'ai découvert que j'ai une restriction dans laquelle je ne peux pas utiliser ces informations d'identification, mais devez-vous authentifier à l'aide d'un rôle d'instance IAM.
Je n'ai pas de chance en faisant ce léger changement de changement.
J'ai créé une stratégie IAM pour permettre à mon utilisateur d'accéder à la file d'attente S3 Seau et SQS, voici:
foopolicy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::foo-demo-bucket"
]
},
{
"Effect": "Allow",
"Action": [
"sqs:*"
],
"Resource": [
"arn:aws:sqs:::mysqsqueue"
]
}
]
}
Ensuite, j'ai créé un rôle IAM à l'aide de cette politique et j'ai créé une relation de confiance pour le rôle permettant à Powerer d'assumer ce rôle
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::1234567890:user/foouser",
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
Je gère l'application d'un terminal Bash où j'ai configuré l'AWS CLI, de sorte que de son point de vue, je suis connecté en tant que pliseur et le pignon a été ajouté au rôle d'entité de confiance.
Cependant, lorsque j'exécute mon application, comme configuré, je reçois l'erreur:
... Le jeton de sécurité inclus dans la demande est invalide. ...
Java -Dconfig.file=./src/main/resources/application.yml -jar ./target/demo-0.0.1-SNAPSHOT.jar
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.7.RELEASE)
2019-08-14 15:39:07.223 INFO 58892 --- [ main] com.example.demo.DemoApplication : Starting DemoApplication v0.0.1-SNAPSHOT on A6485192 with PID 58892 (/Users/foo/bar/src/demos3/target/demo-0.0.1-SNAPSHOT.jar started by foo in /Users/foo/bar/src/demos3)
2019-08-14 15:39:07.225 INFO 58892 --- [ main] com.example.demo.DemoApplication : No active profile set, falling back to default profiles: default
2019-08-14 15:39:10.785 INFO 58892 --- [ main] faultConfiguringBeanFactoryPostProcessor : No bean named 'errorChannel' has been explicitly defined. Therefore, a default PublishSubscribeChannel will be created.
2019-08-14 15:39:10.790 INFO 58892 --- [ main] faultConfiguringBeanFactoryPostProcessor : No bean named 'taskScheduler' has been explicitly defined. Therefore, a default ThreadPoolTaskScheduler will be created.
2019-08-14 15:39:10.793 INFO 58892 --- [ main] faultConfiguringBeanFactoryPostProcessor : No bean named 'integrationHeaderChannelRegistry' has been explicitly defined. Therefore, a default DefaultHeaderChannelRegistry will be created.
2019-08-14 15:39:10.810 INFO 58892 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'credentialsProvider' of type [com.amazonaws.auth.DefaultAWSCredentialsProviderChain] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2019-08-14 15:39:10.824 INFO 58892 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.integration.config.IntegrationManagementConfiguration' of type [org.springframework.integration.config.IntegrationManagementConfiguration$$EnhancerBySpringCGLIB$$364c7eab] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2019-08-14 15:39:10.838 INFO 58892 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'integrationDisposableAutoCreatedBeans' of type [org.springframework.integration.config.annotation.Disposables] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2019-08-14 15:39:11.206 WARN 58892 --- [ main] c.a.a.p.i.BasicProfileConfigLoader : Your profile name includes a 'profile ' prefix. This is considered part of the profile name in the Java SDK, so you will need to include this prefix in your profile name when you reference this profile from your Java code.
2019-08-14 15:39:12.729 WARN 58892 --- [ main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'simpleMessageListenerContainer' defined in class path resource [org/springframework/cloud/aws/messaging/config/annotation/SqsConfiguration.class]: Invocation of init method failed; nested exception is com.amazonaws.services.sqs.model.AmazonSQSException: The security token included in the request is invalid. (Service: AmazonSQS; Status Code: 403; Error Code: InvalidClientTokenId; Request ID: 0b676d6d-5b41-5535-9d31-38a3d491aba6)
2019-08-14 15:39:12.735 INFO 58892 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2019-08-14 15:39:12.740 ERROR 58892 --- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'simpleMessageListenerContainer' defined in class path resource [org/springframework/cloud/aws/messaging/config/annotation/SqsConfiguration.class]: Invocation of init method failed; nested exception is com.amazonaws.services.sqs.model.AmazonSQSException: The security token included in the request is invalid. (Service: AmazonSQS; Status Code: 403; Error Code: InvalidClientTokenId; Request ID: 0b676d6d-5b41-5535-9d31-38a3d491aba6)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.Java:1778) ~[spring-beans-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.Java:593) ~[spring-beans-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.Java:515) ~[spring-beans-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.Java:320) ~[spring-beans-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.Java:222) ~[spring-beans-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.Java:318) ~[spring-beans-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.Java:199) ~[spring-beans-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.Java:845) ~[spring-beans-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.Java:877) ~[spring-context-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.Java:549) ~[spring-context-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.Java:743) [spring-boot-2.1.7.RELEASE.jar!/:2.1.7.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.Java:390) [spring-boot-2.1.7.RELEASE.jar!/:2.1.7.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.Java:312) [spring-boot-2.1.7.RELEASE.jar!/:2.1.7.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.Java:1214) [spring-boot-2.1.7.RELEASE.jar!/:2.1.7.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.Java:1203) [spring-boot-2.1.7.RELEASE.jar!/:2.1.7.RELEASE]
at com.example.demo.DemoApplication.main(DemoApplication.Java:13) [classes!/:0.0.1-SNAPSHOT]
at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_212]
at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:62) ~[na:1.8.0_212]
at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43) ~[na:1.8.0_212]
at Java.lang.reflect.Method.invoke(Method.Java:498) ~[na:1.8.0_212]
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.Java:48) [demo-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
at org.springframework.boot.loader.Launcher.launch(Launcher.Java:87) [demo-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
at org.springframework.boot.loader.Launcher.launch(Launcher.Java:51) [demo-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.Java:52) [demo-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
Caused by: com.amazonaws.services.sqs.model.AmazonSQSException: The security token included in the request is invalid. (Service: AmazonSQS; Status Code: 403; Error Code: InvalidClientTokenId; Request ID: 0b676d6d-5b41-5535-9d31-38a3d491aba6)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleErrorResponse(AmazonHttpClient.Java:1660) ~[aws-Java-sdk-core-1.11.415.jar!/:na]
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.Java:1324) ~[aws-Java-sdk-core-1.11.415.jar!/:na]
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.Java:1074) ~[aws-Java-sdk-core-1.11.415.jar!/:na]
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.Java:745) ~[aws-Java-sdk-core-1.11.415.jar!/:na]
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.Java:719) ~[aws-Java-sdk-core-1.11.415.jar!/:na]
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.Java:701) ~[aws-Java-sdk-core-1.11.415.jar!/:na]
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.Java:669) ~[aws-Java-sdk-core-1.11.415.jar!/:na]
at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.Java:651) ~[aws-Java-sdk-core-1.11.415.jar!/:na]
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.Java:515) ~[aws-Java-sdk-core-1.11.415.jar!/:na]
at com.amazonaws.services.sqs.AmazonSQSClient.doInvoke(AmazonSQSClient.Java:2147) ~[aws-Java-sdk-sqs-1.11.415.jar!/:na]
at com.amazonaws.services.sqs.AmazonSQSClient.invoke(AmazonSQSClient.Java:2116) ~[aws-Java-sdk-sqs-1.11.415.jar!/:na]
at com.amazonaws.services.sqs.AmazonSQSClient.invoke(AmazonSQSClient.Java:2105) ~[aws-Java-sdk-sqs-1.11.415.jar!/:na]
at com.amazonaws.services.sqs.AmazonSQSClient.executeGetQueueUrl(AmazonSQSClient.Java:1138) ~[aws-Java-sdk-sqs-1.11.415.jar!/:na]
at com.amazonaws.services.sqs.AmazonSQSClient.getQueueUrl(AmazonSQSClient.Java:1110) ~[aws-Java-sdk-sqs-1.11.415.jar!/:na]
at org.springframework.cloud.aws.messaging.support.destination.DynamicQueueUrlDestinationResolver.resolveDestination(DynamicQueueUrlDestinationResolver.Java:94) ~[spring-cloud-aws-messaging-2.1.2.RELEASE.jar!/:2.1.2.RELEASE]
at org.springframework.cloud.aws.messaging.support.destination.DynamicQueueUrlDestinationResolver.resolveDestination(DynamicQueueUrlDestinationResolver.Java:38) ~[spring-cloud-aws-messaging-2.1.2.RELEASE.jar!/:2.1.2.RELEASE]
at org.springframework.messaging.core.CachingDestinationResolverProxy.resolveDestination(CachingDestinationResolverProxy.Java:92) ~[spring-messaging-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.springframework.cloud.aws.messaging.listener.AbstractMessageListenerContainer.queueAttributes(AbstractMessageListenerContainer.Java:320) ~[spring-cloud-aws-messaging-2.1.2.RELEASE.jar!/:2.1.2.RELEASE]
at org.springframework.cloud.aws.messaging.listener.AbstractMessageListenerContainer.initialize(AbstractMessageListenerContainer.Java:292) ~[spring-cloud-aws-messaging-2.1.2.RELEASE.jar!/:2.1.2.RELEASE]
at org.springframework.cloud.aws.messaging.listener.SimpleMessageListenerContainer.initialize(SimpleMessageListenerContainer.Java:111) ~[spring-cloud-aws-messaging-2.1.2.RELEASE.jar!/:2.1.2.RELEASE]
at org.springframework.cloud.aws.messaging.listener.AbstractMessageListenerContainer.afterPropertiesSet(AbstractMessageListenerContainer.Java:267) ~[spring-cloud-aws-messaging-2.1.2.RELEASE.jar!/:2.1.2.RELEASE]
at org.springframework.cloud.aws.messaging.listener.SimpleMessageListenerContainer.afterPropertiesSet(SimpleMessageListenerContainer.Java:45) ~[spring-cloud-aws-messaging-2.1.2.RELEASE.jar!/:2.1.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.Java:1837) ~[spring-beans-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.Java:1774) ~[spring-beans-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
... 23 common frames omitted
Merci à quiconque peut m'aider à résoudre ceci
Voici la source de l'application qui démontre mon problème.
DemoApplication.java
package com.example.demo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@Slf4j
@SpringBootApplication
public class DemoApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
while(true) {
Thread.sleep(1000);
}
}
}
Application.yml
cloud:
aws:
stack:
auto: false
credentials:
accessKey:
secretKey:
instanceProfile: true
useDefaultAwsCredentialsChain: true
region:
static: us-east-1
aws:
enabled: true
region: us-east-1
user: foouser
access-key:
secret-key:
sqs:
queue: mysqsqueue
s3:
bucket: foo-demo-bucket
aws.java
package com.example.demo;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.PutObjectResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.aws.messaging.listener.annotation.SqsListener;
import org.springframework.stereotype.Component;
import Java.io.File;
@Slf4j
@Component
public class AWS {
@Autowired
private AmazonS3 amazonS3;
@Value("${aws.s3.bucket}")
private String bucket;
PutObjectResult upload(String filePath, String uploadKey) {
File file = new File(filePath);
return amazonS3.putObject(bucket, uploadKey, file);
}
@SqsListener("mysqsqueue")
public void queueListener(String message) {
System.out.println("Got an SQS message: " + message);
}
}
awsconfiguration.java
package com.example.demo;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.sqs.AmazonSQSAsync;
import com.amazonaws.services.sqs.AmazonSQSAsyncClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.aws.messaging.config.annotation.EnableSqs;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
@Configuration
@EnableSqs
public class AWSConfiguration {
@Value("${aws.region}")
private String awsRegion;
@Value("${aws.access-key}")
private String awsAccessKey;
@Value("${aws.secret-key}")
private String awsSecretKey;
@Bean
@Primary
public AmazonSQSAsync amazonSQSAsyncClient() {
AmazonSQSAsync amazonSQSAsyncClient = AmazonSQSAsyncClientBuilder.standard()
.withCredentials(amazonAWSCredentials())
.withRegion(awsRegion)
.build();
return amazonSQSAsyncClient;
}
@Bean
public AmazonS3 amazonS3Client() {
AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
.withCredentials(amazonAWSCredentials())
.withRegion(awsRegion).build();
return s3Client;
}
@Bean
@Primary
public AWSCredentialsProvider amazonAWSCredentials() {
return new AWSCredentialsProvider() {
public void refresh() {}
public AWSCredentials getCredentials() {
return new AWSCredentials() {
public String getAWSSecretKey() {
return awsSecretKey;
}
public String getAWSAccessKeyId() {
return awsAccessKey;
}
};
}
};
}
}
Votre politique IAM est fausse - la ressource SQS doit inclure des caractères génériques pour la région AWS et l'ID de compte (arn:aws:sqs:*:*:mysqsqueue
à la place de arn:aws:sqs:::mysqsqueue
).
La politique ci-dessous devrait fonctionner.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::foo-demo-bucket"
]
},
{
"Effect": "Allow",
"Action": [
"sqs:*"
],
"Resource": [
"arn:aws:sqs:*:*:mysqsqueue"
]
}
]
}
Il est toujours préférable de confirmer si vos stratégies IAM sont spécifiées correctement en utilisant IAM Simulator car il attrape des erreurs les plus stupides.