我将如何通过AWS参数存储Spring属性源的Java属性公开AWS凭证

时间:2018-06-11 18:29:10

标签: java spring-boot spring-cloud aws-ssm aws-sdk-java-2.0

来自文档:http://cloud.spring.io/spring-cloud-static/spring-cloud-aws/2.0.0.RC2/single/spring-cloud-aws.html#_parameter_store_configuration_credentials_and_region_configuration

  

参数存储配置支持使用引导上下文来配置默认的AWSSimpleSystemsManagement客户端,该客户端使用com.amazonaws.auth.DefaultAWSCredentialsProviderChain和com.amazonaws.regions.DefaultAwsRegionProviderChain

提供商链的文档:https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html

我希望避免使用环境变量或命令行属性,因为这些很可能会泄漏到prod中的某些日志中。我看到的最佳选择是使用.properties文件。根据第一个链接,由于模块是在引导上下文中加载的,我认为“Spring”方法是将这些属性包含在bootstrap.properties文件中(根据spring-cloud docs:{{ 3}})

所以我的项目看起来像这样:

/src/main/resources/bootstrap.properties

aws.accessKeyId = SECRET
aws.secretKey   = ALSOSECRET

的pom.xml

...
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Finchley.RC2</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
...
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-aws-parameter-store-config</artifactId>
        <version>2.0.0.RC2</version>
    </dependency>
</dependencies>
....

请注意,我还公开了AWS_REGION环境变量,这是第一个需要克服的障碍。我正在运行Java 8,并且可以复制从Eclipse和命令行Maven运行的以下行为。

启动时,我得到了这个堆栈跟踪:

2018-06-11 13:20:57.092  INFO 2272 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@359f7cdf: startup date [Mon Jun 11 13:20:57 CDT 2018]; root of context hierarchy
2018-06-11 13:20:57.613  INFO 2272 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'configurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$459ef732] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.0.1.RELEASE)

2018-06-11 13:21:00.301 ERROR 2272 --- [           main] c.a.p.AwsParamStorePropertySourceLocator : Fail fast is set and there was an error reading configuration from AWS Parameter Store:
Unable to load AWS credentials from any provider in the chain
2018-06-11 13:21:00.308 ERROR 2272 --- [           main] o.s.boot.SpringApplication               : Application run failed

com.amazonaws.SdkClientException: Unable to load AWS credentials from any provider in the chain
    at com.amazonaws.auth.AWSCredentialsProviderChain.getCredentials(AWSCredentialsProviderChain.java:131) ~[aws-java-sdk-core-1.11.251.jar:na]
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.getCredentialsFromContext(AmazonHttpClient.java:1164) ~[aws-java-sdk-core-1.11.251.jar:na]
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.runBeforeRequestHandlers(AmazonHttpClient.java:762) ~[aws-java-sdk-core-1.11.251.jar:na]
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:724) ~[aws-java-sdk-core-1.11.251.jar:na]
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:717) ~[aws-java-sdk-core-1.11.251.jar:na]
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:699) ~[aws-java-sdk-core-1.11.251.jar:na]
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:667) ~[aws-java-sdk-core-1.11.251.jar:na]
    at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:649) ~[aws-java-sdk-core-1.11.251.jar:na]
    at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:513) ~[aws-java-sdk-core-1.11.251.jar:na]
    at com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagementClient.doInvoke(AWSSimpleSystemsManagementClient.java:6573) ~[aws-java-sdk-ssm-1.11.251.jar:na]
    at com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagementClient.invoke(AWSSimpleSystemsManagementClient.java:6549) ~[aws-java-sdk-ssm-1.11.251.jar:na]
    at com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagementClient.executeGetParametersByPath(AWSSimpleSystemsManagementClient.java:4204) ~[aws-java-sdk-ssm-1.11.251.jar:na]
    at com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagementClient.getParametersByPath(AWSSimpleSystemsManagementClient.java:4180) ~[aws-java-sdk-ssm-1.11.251.jar:na]
    at org.springframework.cloud.aws.paramstore.AwsParamStorePropertySource.getParameters(AwsParamStorePropertySource.java:67) ~[spring-cloud-aws-parameter-store-config-2.0.0.RC2.jar:2.0.0.RC2]
    at org.springframework.cloud.aws.paramstore.AwsParamStorePropertySource.init(AwsParamStorePropertySource.java:52) ~[spring-cloud-aws-parameter-store-config-2.0.0.RC2.jar:2.0.0.RC2]
    at org.springframework.cloud.aws.paramstore.AwsParamStorePropertySourceLocator.create(AwsParamStorePropertySourceLocator.java:111) ~[spring-cloud-aws-parameter-store-config-2.0.0.RC2.jar:2.0.0.RC2]
    at org.springframework.cloud.aws.paramstore.AwsParamStorePropertySourceLocator.locate(AwsParamStorePropertySourceLocator.java:94) ~[spring-cloud-aws-parameter-store-config-2.0.0.RC2.jar:2.0.0.RC2]
    at org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration.initialize(PropertySourceBootstrapConfiguration.java:94) ~[spring-cloud-context-2.0.0.RC2.jar:2.0.0.RC2]
    at org.springframework.boot.SpringApplication.applyInitializers(SpringApplication.java:633) [spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
    at org.springframework.boot.SpringApplication.prepareContext(SpringApplication.java:373) [spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:325) [spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1255) [spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1243) [spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
    at com.company.app.App.main(App.java:10) [classes/:na]

我是否希望此模块可以看到bootstrap.properties中的属性?我还应该如何为bootstrap上下文提供属性?

1 个答案:

答案 0 :(得分:0)

  

我希望避免使用环境变量或命令行属性,因为这些很可能会泄漏到prod中的某些日志中。

实际上,AWS对此很好,可以为您处理大部分肮脏的工作。您担心的是,您的凭据将立即以日志中的开放纯文本形式存在,并且您希望将凭据存储在由某种版本/ repo系统管理的文件中。 AWS承认这是一个可能的选择,但实际上它表明,由于所涉及的工作量,它并不认为它是最好的解决方案。

https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2.html

  

您可以让开发人员直接在EC2实例中存储AWS凭据,并允许该实例中的应用程序使用这些凭据。但是开发人员必须管理凭据并确保他们安全地将凭证传递给每个实例,并在需要轮换凭证时更新每个EC2实例。这还有很多额外的工作。

您可以将AWS配置为使用IAM角色在部署应用时为EC2实例提供临时凭据。这些角色仅限于您定义的访问权限,并在短期后过期,最多可能是几个小时。

您发布的错误消息在您正确配置的EC2实例中根本不会发生。要在本地测试环境中运行,或者在云端运行,您可以在.aws / credentials存储中提供凭据,而无需提供任何类型的凭据来访问您的QA / PROD EC2框,因为.aws / credentials路径不是& #39; t检查直到环境变量之后。

这样可以立即为您的安全和理智带来好处:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html

  

您无需在应用程序中分发或嵌入长期AWS安全凭证。

     

您可以向用户提供对AWS资源的访问权限,而无需为其定义AWS身份。临时凭证是角色和身份联合的基础。

     

临时安全凭证的生命周期有限,因此您不必轮换它们或在不再需要时明确撤消它们。临时安全凭证到期后,无法重复使用。您可以指定凭据有效的时间长度,直至达到最大限制。