Saltar al contenido

Spring Boot Descarga del archivo del bucket de Amazon AWS S3: acceso denegado

Esta es la respuesta más exacta que encomtrarás dar, pero primero obsérvala pausadamente y valora si es compatible a tu trabajo.

Solución:

Descubrí la solución. Además de la configuración de application.properties, tuve que crear una clase de configuración que me diera acceso a un objeto AmazonS3Client cuando me proporcionaran las credenciales adecuadas. Seguí este ejemplo en 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;
    

Una vez que esto esté configurado, puede crear objetos AmazonS3Client (autowired) en sus otras clases y usar el cliente para realizar solicitudes a su nube S3. El ejemplo utiliza una clase contenedora como servicio para facilitar la implementación de clases de controlador adicionales.

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 upload(MultipartFile[] multipartFiles) 
        List 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 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 list() 
        ObjectListing objectListing = amazonS3Client.listObjects(new ListObjectsRequest().withBucketName(bucket));

        List s3ObjectSummaries = objectListing.getObjectSummaries();

        return s3ObjectSummaries;
    

Nota: La siguiente dependencia deberá agregarse a pom.xml para poder usar la biblioteca IO de Apache Commons.

pom.xml:


    org.apache.commons
    commons-io
    1.3.2

La respuesta aceptada es utilizar API obsoletas. Aquí hay una revisión actualizada.

Primero, actualice sus dependencias maven:

 
        com.amazonaws
        aws-java-sdk
        1.11.274
    

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 upload(MultipartFile[] multipartFiles) 
        List 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 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 list() 
        ObjectListing objectListing = amazonS3.listObjects(new ListObjectsRequest().withBucketName(bucket));

        List s3ObjectSummaries = objectListing.getObjectSummaries();

        return s3ObjectSummaries;
    

Comentarios y calificaciones de la guía

Si estás contento con lo expuesto, tienes la libertad de dejar un tutorial acerca de qué le añadirías a esta división.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *