2016-07-25 98 views
6

AWS、Spring Bootアプリケーションが自動設定されています。エンドポイントをセットアップして、Amazon S3の特定のバケットから特定のファイルをダウンロードします。 AWSコンソールを使用して、自分のコンピュータからJPEGファイルをバケットにアップロードしました。今では、Spring Boot APIを使用してそのファイルをダウンロードしようとしています。SpringブートAmazon AWS S3バケットファイルダウンロード - アクセスが拒否されました

私は次のエラーを取得しています:com.amazonaws.services.s3.model.AmazonS3Exception: Access Denied (Service: Amazon S3; Status Code: 403; Error Code: AccessDenied;

私は、AWSコンソールに(ユーザーがグループ内にある)ユーザとグループを作成しました。ユーザー/グループには、S3および管理者アクセスに対するフルアクセス権が与えられます。私はアクセスキーと秘密鍵のペアをダウンロードし、テスト目的のために文字通り以下のようにキーを私のapplication.propertiesファイルに貼り付けました(明らかにキーはここには表示されません)。

なぜ私はまだアクセスが拒否されているのか混乱しています。私はこれをしばらく探し求めていました。私はSpring Boot特有のこの問題に対する解決策を見つけることができません。どんな助けでも大歓迎です。

application.properties:

cloud.aws.credentials.accessKey=myaccesskey 
cloud.aws.credentials.secretKey=mysecretkey 
cloud.aws.credentials.instanceProfile=false 
cloud.aws.stack.auto=false 

cloud.aws.region.auto=true 
cloud.aws.region.static=myregion 

SimpleResourceLoadingBean.java:

@RestController 
public class SimpleResourceLoadingBean { 

    private static Logger log = LoggerFactory.getLogger(HealthMonitorApplication.class); 

    @Autowired 
    private ResourceLoader resourceLoader; 


    @RequestMapping("/getresource") 
    public String resourceLoadingMethod() throws IOException { 
     log.info("IN RESOURCE LOADER"); 

     Resource resource = this.resourceLoader.getResource("s3://s3.amazonaws.com/mybucket/myfile.ext"); 

     InputStream inputStream = resource.getInputStream(); 

     return inputStream.toString(); 
    } 
} 

のpom.xml(質問に関連しているだけで依存関係)

 <dependency> 
      <groupId>org.springframework.cloud</groupId> 
      <artifactId>spring-cloud-starter-aws</artifactId> 
      <version>1.1.0.RELEASE</version> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.cloud</groupId> 
      <artifactId>spring-cloud-aws-autoconfigure</artifactId> 
      <version>1.1.0.RELEASE</version> 
     </dependency> 
+0

trueに変更して動作するかどうかを確認します。 – error2007s

+0

試行錯誤:1 – corecase

+0

上記のSpringアプリケーションは、ローカルまたはEC2インスタンスにありますか? – error2007s

答えて

13

を考え出しました溶液。 application.propertiesの設定以外にも、適切な資格情報が提供された場合、AmazonS3Clientオブジェクトにアクセスできるようにするための設定クラスを作成する必要がありました。私はGitHubの上でこの例を踏襲:

https://github.com/brant-hwang/spring-cloud-aws-example/blob/master/src/main/java/com/axisj/spring/cloud/aws/AWSConfiguration.java

AWSConfiguration.java:これを設定すると、あなたは他のクラスでAmazonS3Clientオブジェクトを(autowired)を作成、および、クライアントを使用することができます

import com.amazonaws.auth.AWSCredentials; 
import com.amazonaws.auth.BasicAWSCredentials; 
import com.amazonaws.regions.Region; 
import com.amazonaws.regions.Regions; 
import com.amazonaws.services.s3.AmazonS3Client; 
import org.springframework.beans.factory.annotation.Value; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 

@Configuration 
public class AWSConfiguration { 

    @Value("${cloud.aws.credentials.accessKey}") 
    private String accessKey; 

    @Value("${cloud.aws.credentials.secretKey}") 
    private String secretKey; 

    @Value("${cloud.aws.region}") 
    private String region; 

    @Bean 
    public BasicAWSCredentials basicAWSCredentials() { 
     return new BasicAWSCredentials(accessKey, secretKey); 
    } 

    @Bean 
    public AmazonS3Client amazonS3Client(AWSCredentials awsCredentials) { 
     AmazonS3Client amazonS3Client = new AmazonS3Client(awsCredentials); 
     amazonS3Client.setRegion(Region.getRegion(Regions.fromName(region))); 
     return amazonS3Client; 
    } 
} 

S3クラウドへのリクエストを作成します。この例では、追加のコントローラクラスの実装を容易にするために、ラッパークラスをサービスとして使用しています。

S3Wrapper.java:

import com.amazonaws.services.s3.AmazonS3Client; 
import com.amazonaws.services.s3.model.*; 
import org.apache.commons.io.IOUtils; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.beans.factory.annotation.Value; 
import org.springframework.http.HttpHeaders; 
import org.springframework.http.HttpStatus; 
import org.springframework.http.MediaType; 
import org.springframework.http.ResponseEntity; 
import org.springframework.stereotype.Service; 
import org.springframework.util.StringUtils; 
import org.springframework.web.multipart.MultipartFile; 

import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.IOException; 
import java.io.InputStream; 
import java.net.URLEncoder; 
import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.List; 

@Service 
public class S3Wrapper { 

    @Autowired 
    private AmazonS3Client amazonS3Client; 

    @Value("${cloud.aws.s3.bucket}") 
    private String bucket; 

    private PutObjectResult upload(String filePath, String uploadKey) throws FileNotFoundException { 
     return upload(new FileInputStream(filePath), uploadKey); 
    } 

    private PutObjectResult upload(InputStream inputStream, String uploadKey) { 
     PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, uploadKey, inputStream, new ObjectMetadata()); 

     putObjectRequest.setCannedAcl(CannedAccessControlList.PublicRead); 

     PutObjectResult putObjectResult = amazonS3Client.putObject(putObjectRequest); 

     IOUtils.closeQuietly(inputStream); 

     return putObjectResult; 
    } 

    public List<PutObjectResult> upload(MultipartFile[] multipartFiles) { 
     List<PutObjectResult> putObjectResults = new ArrayList<>(); 

     Arrays.stream(multipartFiles) 
       .filter(multipartFile -> !StringUtils.isEmpty(multipartFile.getOriginalFilename())) 
       .forEach(multipartFile -> { 
        try { 
         putObjectResults.add(upload(multipartFile.getInputStream(), multipartFile.getOriginalFilename())); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 
       }); 

     return putObjectResults; 
    } 

    public ResponseEntity<byte[]> download(String key) throws IOException { 
     GetObjectRequest getObjectRequest = new GetObjectRequest(bucket, key); 

     S3Object s3Object = amazonS3Client.getObject(getObjectRequest); 

     S3ObjectInputStream objectInputStream = s3Object.getObjectContent(); 

     byte[] bytes = IOUtils.toByteArray(objectInputStream); 

     String fileName = URLEncoder.encode(key, "UTF-8").replaceAll("\\+", "%20"); 

     HttpHeaders httpHeaders = new HttpHeaders(); 
     httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM); 
     httpHeaders.setContentLength(bytes.length); 
     httpHeaders.setContentDispositionFormData("attachment", fileName); 

     return new ResponseEntity<>(bytes, httpHeaders, HttpStatus.OK); 
    } 

    public List<S3ObjectSummary> list() { 
     ObjectListing objectListing = amazonS3Client.listObjects(new ListObjectsRequest().withBucketName(bucket)); 

     List<S3ObjectSummary> s3ObjectSummaries = objectListing.getObjectSummaries(); 

     return s3ObjectSummaries; 
    } 
} 

注:次の依存関係は、Apache CommonsのIOライブラリを使用するためにのpom.xmlに追加する必要があります。

のpom.xml:

<dependency> 
    <groupId>org.apache.commons</groupId> 
    <artifactId>commons-io</artifactId> 
    <version>1.3.2</version> 
</dependency> 
+0

しかし、spring-bootはEnableAutoConfigurationアノテーションを設定クラスの1つに追加することで自動設定を提供します。 awsを設定しない。 – M05

2

受け入れ答えは推奨されないAPIを使用しています。ここに更新版があります。

まず、あなたのMavenの依存関係を更新します。

<dependency> 
     <groupId>com.amazonaws</groupId> 
     <artifactId>aws-java-sdk</artifactId> 
     <version>1.11.274</version> 
    </dependency> 

AWSConfiguration.java

import com.amazonaws.auth.AWSCredentials; 
import com.amazonaws.auth.AWSStaticCredentialsProvider; 
import com.amazonaws.auth.BasicAWSCredentials; 
import com.amazonaws.services.s3.AmazonS3; 
import com.amazonaws.services.s3.AmazonS3ClientBuilder; 
import org.springframework.beans.factory.annotation.Value; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 

@Configuration 
public class AWSConfiguration { 

    @Value("${cloud.aws.credentials.accessKey}") 
    private String accessKey; 

    @Value("${cloud.aws.credentials.secretKey}") 
    private String secretKey; 

    @Value("${cloud.aws.region}") 
    private String region; 

    @Bean 
    public BasicAWSCredentials basicAWSCredentials() { 
     return new BasicAWSCredentials(accessKey, secretKey); 
    } 

    @Bean 
    public AmazonS3 amazonS3Client(AWSCredentials awsCredentials) { 
     AmazonS3ClientBuilder builder = AmazonS3ClientBuilder.standard(); 
     builder.withCredentials(new AWSStaticCredentialsProvider(awsCredentials)); 
     builder.setRegion(region); 
     AmazonS3 amazonS3 = builder.build(); 
     return amazonS3; 
    } 
} 

S3Service。java

import com.amazonaws.services.s3.AmazonS3; 
import com.amazonaws.services.s3.AmazonS3Client; 
import com.amazonaws.services.s3.model.*; 
import org.apache.commons.io.IOUtils; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.beans.factory.annotation.Value; 
import org.springframework.http.HttpHeaders; 
import org.springframework.http.HttpStatus; 
import org.springframework.http.MediaType; 
import org.springframework.http.ResponseEntity; 
import org.springframework.stereotype.Service; 
import org.springframework.util.StringUtils; 
import org.springframework.web.multipart.MultipartFile; 

import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.IOException; 
import java.io.InputStream; 
import java.net.URLEncoder; 
import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.List; 

@Service 
public class S3Service { 

    @Autowired 
    private AmazonS3 amazonS3; 

    @Value("${cloud.aws.s3.bucket}") 
    private String bucket; 

    private PutObjectResult upload(String filePath, String uploadKey) throws FileNotFoundException { 
     return upload(new FileInputStream(filePath), uploadKey); 
    } 

    private PutObjectResult upload(InputStream inputStream, String uploadKey) { 
     PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, uploadKey, inputStream, new ObjectMetadata()); 

     putObjectRequest.setCannedAcl(CannedAccessControlList.PublicRead); 

     PutObjectResult putObjectResult = amazonS3.putObject(putObjectRequest); 

     IOUtils.closeQuietly(inputStream); 

     return putObjectResult; 
    } 

    public List<PutObjectResult> upload(MultipartFile[] multipartFiles) { 
     List<PutObjectResult> putObjectResults = new ArrayList<>(); 

     Arrays.stream(multipartFiles) 
       .filter(multipartFile -> !StringUtils.isEmpty(multipartFile.getOriginalFilename())) 
       .forEach(multipartFile -> { 
        try { 
         putObjectResults.add(upload(multipartFile.getInputStream(), multipartFile.getOriginalFilename())); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 
       }); 

     return putObjectResults; 
    } 

    public ResponseEntity<byte[]> download(String key) throws IOException { 
     GetObjectRequest getObjectRequest = new GetObjectRequest(bucket, key); 

     S3Object s3Object = amazonS3.getObject(getObjectRequest); 

     S3ObjectInputStream objectInputStream = s3Object.getObjectContent(); 

     byte[] bytes = IOUtils.toByteArray(objectInputStream); 

     String fileName = URLEncoder.encode(key, "UTF-8").replaceAll("\\+", "%20"); 

     HttpHeaders httpHeaders = new HttpHeaders(); 
     httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM); 
     httpHeaders.setContentLength(bytes.length); 
     httpHeaders.setContentDispositionFormData("attachment", fileName); 

     return new ResponseEntity<>(bytes, httpHeaders, HttpStatus.OK); 
    } 

    public List<S3ObjectSummary> list() { 
     ObjectListing objectListing = amazonS3.listObjects(new ListObjectsRequest().withBucketName(bucket)); 

     List<S3ObjectSummary> s3ObjectSummaries = objectListing.getObjectSummaries(); 

     return s3ObjectSummaries; 
    } 
} 
関連する問題