【问题标题】:AWS S3 Java file upload without access keys/credentials无需访问密钥/凭证的 AWS S3 Java 文件上传
【发布时间】:2018-01-31 13:28:58
【问题描述】:


我是 AWS 新手,
我使用 AWS CLI 在本地配置我的 AWS 凭证,因为我无法将 IAM 角色附加到我的笔记本电脑,
通过 Eclipse IDE 的 AWS 工具包插件,我可以看到我的凭证已正确配置。
我提到了这个答案 - AWS S3 upload without access and secret key in Java,

谁能帮我理解如何在代码中设置 S3 存储桶位于哪个区域?
还是从 aws configure 命令期间的一组中获取区域?
当我尝试使用 s3client.setRegion 方法时出现错误。

我无法在本地测试此代码,它向我抛出以下错误 -

com.amazonaws.SdkClientException: Unable to load credentials from service endpoint

以下是我将文件上传到 AWS S3 的代码 -

AmazonS3 s3client = AmazonS3ClientBuilder.standard()
                      .withCredentials(new InstanceProfileCredentialsProvider(false))
                      .build();
//s3client.setRegion(com.amazonaws.regions.Region.getRegion(Regions.EU_CENTRAL_1));
PutObjectResult result = s3client.putObject(new PutObjectRequest(BUCKET_NAME, BASE_PATH + localFile.getName(), localFile));

完整的错误日志 -

The legacy profile format requires the 'profile ' prefix before the profile name. The latest code does not require such prefix, and will consider it as part of the profile name. Please remove the prefix if you are seeing this warning.
com.amazonaws.SdkClientException: Unable to load credentials from service endpoint
    at com.amazonaws.auth.EC2CredentialsFetcher.handleError(EC2CredentialsFetcher.java:180)
    at com.amazonaws.auth.EC2CredentialsFetcher.fetchCredentials(EC2CredentialsFetcher.java:159)
    at com.amazonaws.auth.EC2CredentialsFetcher.getCredentials(EC2CredentialsFetcher.java:82)
    at com.amazonaws.auth.InstanceProfileCredentialsProvider.getCredentials(InstanceProfileCredentialsProvider.java:141)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.getCredentialsFromContext(AmazonHttpClient.java:1118)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.runBeforeRequestHandlers(AmazonHttpClient.java:758)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:722)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:715)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:697)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:665)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:647)
    at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:511)
    at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:4227)
    at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:4174)
    at com.amazonaws.services.s3.AmazonS3Client.putObject(AmazonS3Client.java:1722)
    at com.atrium.crud.service.PedestrianServiceImpl.savePedestrianSurvey(PedestrianServiceImpl.java:73)
    at com.atrium.crud.controller.PedestrianController.savePedestrianSurvey(PedestrianController.java:69)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:116)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:474)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:783)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:798)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1434)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.net.SocketTimeoutException: connect timed out
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.net.Socket.connect(Socket.java:589)
    at sun.net.NetworkClient.doConnect(NetworkClient.java:175)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:463)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:558)
    at sun.net.www.http.HttpClient.<init>(HttpClient.java:242)
    at sun.net.www.http.HttpClient.New(HttpClient.java:339)
    at sun.net.www.http.HttpClient.New(HttpClient.java:357)
    at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1202)
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1138)
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1032)
    at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:966)
    at com.amazonaws.internal.ConnectionUtils.connectToEndpoint(ConnectionUtils.java:47)
    at com.amazonaws.internal.EC2CredentialsUtils.readResource(EC2CredentialsUtils.java:106)
    at com.amazonaws.internal.EC2CredentialsUtils.readResource(EC2CredentialsUtils.java:77)
    at com.amazonaws.auth.InstanceProfileCredentialsProvider$InstanceMetadataCredentialsEndpointProvider.getCredentialsEndpoint(InstanceProfileCredentialsProvider.java:156)
    at com.amazonaws.auth.EC2CredentialsFetcher.fetchCredentials(EC2CredentialsFetcher.java:121)
    ... 69 more

【问题讨论】:

    标签: java amazon-web-services file-upload amazon-s3


    【解决方案1】:

    你可以使用:

    AmazonS3Client amazons3 = new AmazonS3Client(new ProfileCredentialsProvider());
    

    ProfileCredentialsProvider 将在您的主目录中找到隐藏文件夹 .aws 和文件凭据。

    【讨论】:

      【解决方案2】:

      更好的解决方案是使用凭据提供程序链。这样,您的应用程序就可以在生产环境中使用实例配置文件凭据,并回退到您的开发机器上的配置文件凭据。

      例如:

      AWSCredentialsProviderChain providerChain = new AWSCredentialsProviderChain(
                  InstanceProfileCredentialsProvider.getInstance(),
                  new ProfileCredentialsProvider()
          );
      
      AmazonS3 s3client = AmazonS3ClientBuilder.standard()
                        .withCredentials(providerChain)
                        .build();
      

      这将首先尝试实例配置文件以获取访问权限并回退到配置文件凭据。您可以添加任意数量的提供程序,只要它们实现了the AWSCredentialsProvider interface

      或者,使用default provider chain,它将按此顺序尝试提供者:

      • 环境变量 - AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY(推荐,因为它们被除 .NET 之外的所有 AWS 开发工具包和 CLI 识别),或 AWS_ACCESS_KEYAWS_SECRET_KEY(仅被 Java SDK 识别)
      • Java 系统属性 - aws.accessKeyIdaws.secretKey
      • 所有 AWS 开发工具包和 AWS CLI 共享的默认位置 (~/.aws/credentials) 的凭证配置文件
      • 如果设置了 AWS_CONTAINER_CREDENTIALS_RELATIVE_URI 环境变量并且安全管理员有权访问该变量,则通过 Amazon EC2 容器服务交付凭证,
      • 通过 Amazon EC2 元数据服务交付的实例配置文件凭证

      Source

      【讨论】:

        【解决方案3】:

        试试这个:

        s3Client = new AmazonS3Client(new ClasspathPropertiesFileCredentialsProvider());
        

        确保您的 aws.properties(具有以下键)在类路径中

        accessKey=AKIAIB6FA52IMGLREIIB
        secretKey=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
        

        【讨论】:

        • 当我执行 aws configure 并设置我的凭据时,我认为它们存储在 ~/.aws/config 位置,我在触发以下命令时发现 - aws configure list,是正确的位置?
        • 这是正确的。这些凭证将在使用 AWS CLI 时使用。如果您想从 Java 代码访问服务;这种方式可以正常工作。
        【解决方案4】:

        您需要在构建器语句中插入区域,例如

        AmazonS3 s3client = AmazonS3ClientBuilder.standard()
                 .withCredentials(newInstanceProfileCredentialsProvider(false))
                 .withRegion("eu_central_1")
                 .build();
        

        【讨论】:

          【解决方案5】:

          试试这个

          AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                             .withCredentials(new EnvironmentVariableCredentialsProvider())
                             .build();
          

          【讨论】:

            【解决方案6】:

            我遇到了“无法从服务端点加载凭据”这个问题 我试过这个并且工作正常,不要使用 InstanceProfileCredentialsProvider.getInstance()

            @Bean
            public AmazonS3 getS3Client() {
              return AmazonS3ClientBuilder.standard()
                  .withCredentials(DefaultAWSCredentialsProviderChain.getInstance())
                  .withRegion(Regions.AP_SOUTHEAST_1).build();
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2020-12-19
              • 2013-08-11
              • 2020-02-19
              • 2023-01-25
              • 2019-04-22
              • 1970-01-01
              • 2017-05-05
              相关资源
              最近更新 更多