AWS 从 S3 下载对象时出错,“配置文件不能为空”

Posted

技术标签:

【中文标题】AWS 从 S3 下载对象时出错,“配置文件不能为空”【英文标题】:AWS error downloading object from S3, "profile file cannot be null" 【发布时间】:2017-06-07 08:56:58 【问题描述】:

我已经看过this,但没有答案来解释我的问题。我首先使用了here(GetObject 类)提供的示例,它立即在我的桌面上运行。但是,我的朋友无法让它在他的机器上运行,也无法在我们的 EC2 实例上运行。

有人提到要指定凭据文件,这是有道理的,但我从来不必这样做,并且很确定默认权限已设置为启用访问此存储桶。

这是堆栈跟踪:

Exception in thread "main" java.lang.IllegalArgumentException: profile file cannot be null
    at com.amazonaws.util.ValidationUtils.assertNotNull(ValidationUtils.java:37)
    at com.amazonaws.auth.profile.ProfilesConfigFile.<init>(ProfilesConfigFile.java:142)
    at com.amazonaws.auth.profile.ProfilesConfigFile.<init>(ProfilesConfigFile.java:133)
    at com.amazonaws.auth.profile.ProfilesConfigFile.<init>(ProfilesConfigFile.java:100)
    at com.amazonaws.auth.profile.ProfileCredentialsProvider.getCredentials(ProfileCredentialsProvider.java:135)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.getCredentialsFromContext(AmazonHttpClient.java:1029)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1049)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:949)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:662)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:636)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:619)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$300(AmazonHttpClient.java:587)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:574)
    at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:446)
    at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:4035)
    at com.amazonaws.services.s3.AmazonS3Client.getBucketRegionViaHeadRequest(AmazonS3Client.java:4474)
    at com.amazonaws.services.s3.AmazonS3Client.fetchRegionFromCache(AmazonS3Client.java:4448)
    at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:4020)
    at com.amazonaws.services.s3.AmazonS3Client.getObject(AmazonS3Client.java:1307)
    at GetObject.main(GetObject.java:26)

我可以保证 GetObjectRequest 中的 bucketName 和 key params 都不为空。这里有什么差异?为什么它只能在我的 PC 上成功?这是否与我必须补充 aws-sdk jar 应该已经拥有的许多 jar 的事实有关(jackson-databind、jackson-core、jackson-annotations、httpclient、httpcore、commons-logging 和 joda-时间)?看起来很相似,否则会出现无法解释的错误(给出非空参数,aws-sdk 中的某些内容说它是空的)。

【问题讨论】:

不确定你是否看过这个:***.com/a/41670728/3770040 我仍在查看您的链接以及从中链接的“使用 AWS 凭证”页面,但我从未为我的 Eclipse 项目设置这些,而且我没有凭证文件。我只是开箱即用地运行示例,它运行良好。我还是一头雾水。 好的,我想我发现了问题:我认为凭据会存储在项目文件夹中,但我完全忘记了 ~/.aws/credentials 文件,尽管它是黑色的和我链接的问题中的白色。我只需要知道如何为在我的 EC2 实例上运行的 jar 进行设置。 作为一般规则,请记住,就安全性而言,始终建议使用 EC2 角色,而不是在实例存储中存储用户凭据的配置文件。 【参考方案1】:

看起来您在 cmets 中解决了这个问题,但我对此感到很恼火,想为未来的读者留下更清晰的答案。非常清楚,这里的问题与 S3 中的文件无关。此错误消息与您的硬盘驱动器上的文件或您尝试从 S3 推送/拉取的文件无关。问题是您正在使用以下内容初始化 S3:

AmazonS3 s3Client = new AmazonS3Client(new ProfileCredentialsProvider());

当您这样做时,它会在 ~/.aws/credentials 中查找配置文件列表。这可能在您的计算机上运行良好,但在您通过 IAM 角色(例如 Lambda、Docker、EC2 实例等)获得 AWS 访问权限的任何地方都不起作用。修复方法是像这样初始化 AmazonS3Client:

AmazonS3 s3Client = new AmazonS3Client();

如果您使用的代码需要某种凭据提供程序,您也可以这样做:

AmazonS3 s3Client = new AmazonS3Client(DefaultAWSCredentialsProviderChain.getInstance());

希望对下一个人有所帮助。就我而言,我使用的是 DynamoDB 和 SQS,但我遇到了同样的错误。我最初忽略了这个问题,因为我认为您的问题与 S3 相关并且非常困惑。手腕被打了。

在较新版本的 SDK 上,您需要使用以下代码:

AmazonS3 s3Client = AmazonS3ClientBuilder.standard()                  
                      .withCredentials(DefaultAWSCredentialsProviderChain.getInstance())
                      .build();

【讨论】:

【参考方案2】:

Ryan 投票率最高的答案让我走上了正轨,但由于 AmazonS3Client 现在已被弃用,这段代码为我解决了问题

    AmazonS3 s3 = AmazonS3ClientBuilder.standard()
                  .withCredentials(DefaultAWSCredentialsProviderChain.getInstance())
                  .build();

此代码似乎正确地选择了活动的 IAM 角色,例如在 Lambda 中。

【讨论】:

【参考方案3】:

原因是你朋友的电脑没有“凭证”文件。

要解决问题,请创建文件:

C:\Users\USERNAME \.aws\credentials"

对于 Windows,或创建文件:

~/.aws/credentials

适用于 macOS、Linux 或 Unix。然后写

aws_access_key_id = your_access_key_id
aws_secret_access_key = your_secret_access_key"

进入文件。

或者,也可以设置aws_access_key_idaws_secret_access_key的环境变量。

【讨论】:

抱歉忘记了文件头前面的[default]。 如果您打算在 EC2 实例、ECS、Fargate、Lambda 等上使用您的代码,那么这可能不适合您。不要依赖文件作为获得信誉的唯一途径。 确保credentials文件实际上是在程序运行的用户下创建的;例如如果您的应用程序是守护进程并以用户 foo 身份运行,则该文件应位于 /home/foo/.aws/... 并且如果您碰巧使用 sudo 运行,则该文件应该(显然)位于 @987654330 @【参考方案4】:

我已经使用了以下代码并为我工作,希望它会有所帮助

       BasicAWSCredentials credentials = new BasicAWSCredentials(accesskey, secretkey);

            AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                    .withCredentials(new AWSStaticCredentialsProvider(credentials))
                    .withRegion("ap-south-1")
                    .build();   

【讨论】:

【参考方案5】:

BasicAWSCredentials 可能需要所有三个组件;

BasicAWSCredentials credentials = new BasicAWSCredentials(accesskey, secretkey, accessToken);

另外,请考虑凭据是否来自您的 .aws 文件夹,或者您提供的只是上面的BasicCredentials 行。

【讨论】:

以上是关于AWS 从 S3 下载对象时出错,“配置文件不能为空”的主要内容,如果未能解决你的问题,请参考以下文章

使用 Psycopg2 将数据从 S3 复制到 AWS Redshift 时出错

如何使用AWS SDK从S3下载对象--RESTful。

如何使用AWS SDK从S3下载对象--RESTful。

使用 pyspark 从 AWS s3 Bucket 读取 csv 时出错

如何使用 AWS 开发工具包从 S3 下载对象 - RESTful

从 S3 下载文件时,AWS Lambda 中出现“只读文件系统”错误