Spring Boot Buzz Amazon AWS S3 Boot File - Access Denied

I have an AWS application with AWS auto-tuning, Spring, and I'm trying to configure an endpoint that just loads a specific file from this bucket into Amazon S3. I uploaded a JPEG file to a bucket from my computer using the AWS console - now I am trying to upload this file using my Spring upload API.

I get the following error: com.amazonaws.services.s3.model.AmazonS3Exception: Access Denied (Service: Amazon S3; Status Code: 403; Error Code: AccessDenied;

I created a user and group (user in group) in the AWS console; The user / group has full access rights to S3, as well as administrator access. I downloaded a pair of access key / secret key and, for testing purposes, literally inserted the keys into the application.properties file, as shown below (the keys are not shown here, obviously :)).

I am confused why I am still being refused. I searched and worked on this for a while; I can not find a solution to this problem, which is typical for Spring Boot. Any help would be greatly appreciated.

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 (Only dependencies related to the question)

  <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> 
+7
source share
2 answers

We figured out a solution. In addition to the application.properties configuration, I had to create a configuration class that would give me access to the AmazonS3Client object when providing the appropriate credentials. I followed this example on GitHub:

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

AWSConfiguration.java:

 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; } } 

Once this is configured, you can create AmazonS3Client (autowired) objects in other classes and use the client for queries in the S3 cloud. The example uses a wrapper class as a service to facilitate the implementation of additional controller classes.

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; } } 

Note. To use the Apache Commons I / O library, you must add the following dependency for pom.xml.

pom.xml:

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

The accepted answer uses outdated APIs. Here is the updated version.

First update your maven dependencies:

  <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; } } 
+4
source

All Articles