无法从 Spring Cloud Stream Kinesis binder 链中的任何提供商加载 AWS 凭证

Posted

技术标签:

【中文标题】无法从 Spring Cloud Stream Kinesis binder 链中的任何提供商加载 AWS 凭证【英文标题】:Unable to load AWS credentials from any provider in the chain Spring Cloud Stream Kinesis binder 【发布时间】:2019-12-22 12:33:29 【问题描述】:

如果不使用系统级别的默认配置,我无法在 Spring Cloud Stream Kinesis binder (1.2.0.RELEASE) 中连接到 AWS kinesis。仅当系统已配置为使用默认配置文件并且访问密钥 ID 和秘密访问密钥设置为使用 [默认] 配置文件时,应用程序才能正常工作。否则,它无法通过抛出此异常连接到 AWS 资源:

Caused by: com.amazonaws.SdkClientException: Unable to load AWS credentials from any provider in the chain: [com.amazonaws.auth.EC2ContainerCredentialsProviderWrapper@3b2c8bda: Unable to load credentials from service endpoint, com.amazonaws.auth.profile.ProfileCredentialsProvider@688d619c: No AWS profile named 'default']
    at com.amazonaws.auth.AWSCredentialsProviderChain.getCredentials(AWSCredentialsProviderChain.java:136)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.getCredentialsFromContext(AmazonHttpClient.java:1225)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.runBeforeRequestHandlers(AmazonHttpClient.java:801)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:751)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:744)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:726)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:686)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:668)
    at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:532)
    at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:512)
    at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.doInvoke(AmazonDynamoDBClient.java:3768)
    at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.invoke(AmazonDynamoDBClient.java:3737)
    at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.executeDescribeTable(AmazonDynamoDBClient.java:1836)
    at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.describeTable(AmazonDynamoDBClient.java:1804)
    at com.amazonaws.services.dynamodbv2.document.Table.describe(Table.java:137)
    at org.springframework.integration.aws.metadata.DynamoDbMetadataStore.afterPropertiesSet(DynamoDbMetadataStore.java:145)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1837)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1774)

我尝试了以下选项,但没有一个对我有用:

设置环境变量AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY 设置Java系统属性aws.accessKeyIdaws.secretKeyapplication.yml 文件中设置cloud.aws.credentials.accessKeycloud.aws.credentials.secretKey

【问题讨论】:

【参考方案1】:

我解决了这个问题。

我认为spring-cloud-starter-aws 无法自动配置。 所以我像这样以编程方式设置访问密钥和密钥:

@Configuration
class AWSS3Configuration 

  @Value("\$cloud.aws.credentials.access-key")
  val accessKey: String = ""

  @Value("\$cloud.aws.credentials.secret-key")
  val secretKey: String = ""

  @Bean
  fun amazonS3(): AmazonS3 =
    AmazonS3ClientBuilder.standard()
      .withCredentials(AWSStaticCredentialsProvider(BasicAWSCredentials(accessKey, secretKey)))
      .build()


【讨论】:

【参考方案2】:

似乎由于某种原因 AWSCredentialProvider bean 加载不正确,所以我可以通过设置以下 bean 来临时解决这个问题。这不是一个正确的解决方法,但它确实解除了我的工作:

@Configuration
public class AWSCredentialProvider 
  @Value("$aws.access-key")
  protected String accessKey;

  @Value("$aws.secret-key")
  protected String secretKey;

  @Bean
  @Primary
  public AWSCredentialsProvider buildAWSCredentialsProvider() 
    AWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, secretKey);
    return new AWSStaticCredentialsProvider(awsCredentials);
  

【讨论】:

【参考方案3】:

这简直把我逼疯了。仔细追踪AWS代码后发现,如果将系统属性cloud.aws.credentials.use-default-aws-credentials-chain设置为true,在 DefaultAWSCredentialsProviderChain 中切换。否则,它使用由两个提供者组成的链 - EC2ContainerCredentialsProviderWrapper 和 ProfileCredentialsProvider。这适用于 Spring Boot 2.3.4。对于版本 2.2.5,系统属性是 cloud.aws.credentials.useDefaultAwsCredentialsChain。我还没有研究它更改为烤肉串盒的版本。如果没有这个,它将忽略在环境变量或系统属性中传递的凭据。此代码在 ContextCredentialsAutoConfiguration.registerBeanDefinitions() 中。

【讨论】:

kebab-case 与 Spring 宽松绑定的连字符不一样吗?

以上是关于无法从 Spring Cloud Stream Kinesis binder 链中的任何提供商加载 AWS 凭证的主要内容,如果未能解决你的问题,请参考以下文章

无法在 Spring Cloud 中获取 /hystrix.stream

使用 Spring Cloud Stream Kafka Binder 时无法设置 groupId 和 clientId

无法使用 Spring Cloud 连接到 Hystrix Dashboard 的 Command Metric Stream

Spring Cloud Stream Kafka Streams Binder KafkaException:无法启动流:“侦听器”不能为空

如何在spring cloud stream和kafka中从同一主题发送和接收

Spring Cloud Stream消息JSON转换无效