

# Gerar um URL pré-assinado para carregar um objeto em um bucket do S3 no Outposts
<a name="S3OutpostsPresignedUrlUploadObject"></a>

Você pode usar um URL pré-assinado para conceder acesso por tempo limitado a objetos armazenados localmente em um Outpost sem atualizar sua política de bucket. Com URLs pré-assinados, como proprietário do bucket, você pode compartilhar objetos com indivíduos em sua nuvem privada virtual (VPC) ou conceder a eles a capacidade de carregar ou excluir objetos. 

Ao criar um URL pré-assinado usando os AWS SDKs ou a AWS Command Line Interface (AWS CLI), você associa o URL a uma ação específica. Você também concede acesso por tempo limitado ao URL pré-assinado escolhendo um tempo de expiração personalizado a partir de 1 segundo e de até 7 dias. Ao compartilhar o URL pré-assinado, o indivíduo na VPC pode executar a ação incorporada no URL como se fosse o usuário da assinatura original. Ao atingir o tempo de expiração, o URL expira e não funciona mais.

Ao criar um URL pré-assinado, você deve fornecer suas credenciais de segurança e especificar o seguinte: 
+ Um nome do recurso da Amazon (ARN) de ponto de acesso para o bucket do Amazon S3 no Outposts
+ Uma chave de objeto
+ Um método HTTP (`PUT` para carregar objetos)
+ Data e hora de expiração

Os URLs pré-assinados só são válidos pela duração especificada. Ou seja, é necessário iniciar a ação permitida pelo URL antes da data e da hora de expiração. É possível usar o URL pré-assinado várias vezes até a data e a hora de expiração. Se tiver criado um URL pré-assinado usando um token temporário, o URL expirará quando o token expirar, mesmo que você tenha criado o URL com um tempo de expiração posterior. 

Se a ação permitida por um URL pré-assinado consistir em várias etapas, como um multipart upload, é necessário iniciar todas as etapas antes do tempo de expiração. Você receberá um erro se o S3 no Outposts tentar iniciar uma etapa com um URL expirado.

Os usuários na nuvem privada virtual (VPC) que tiverem acesso ao URL pré-assinado poderão carregar objetos. Por exemplo, um usuário na VPC que tenha acesso ao URL pré-assinado pode carregar um objeto para o seu bucket. Como os URLs pré-assinados concedem acesso aos seus buckets do S3 no Outposts a qualquer usuário na VPC que tenha acesso ao URL pré-assinado, recomendamos proteger esses URLs adequadamente. Para obter mais detalhes sobre como proteger pre-signed URLs, consulte [Limitar recursos de pre-signed URLs](S3OutpostsPresignedURL.md#S3OutpostsPresignedUrlUploadObjectLimitCapabilities). 

Qualquer um com credenciais de segurança válidas pode criar um pre-signed URL. No entanto, o URL pré-assinado deve ter sido criado por alguém que tenha permissão para executar a operação na qual o URL pré-assinado é baseado. Para obter mais informações, consulte [Quem pode criar um URL pré-assinado](S3OutpostsPresignedURL.md#S3Outpostswho-presigned-url).

## Usar os AWS SDKs para gerar um URL pré-assinado para uma operação de objeto do S3 no Outposts
<a name="s3-outposts-presigned-urls-upload-examples"></a>

------
#### [ Java ]

**SDK para Java 2.x**  
Este exemplo mostra como gerar um URL pré-assinado que você pode usar para carregar um objeto em um bucket do S3 no Outposts por um tempo limitado. Para obter mais informações, consulte [Uso de URLs pré-assinados para o S3 no Outposts](S3OutpostsPresignedURL.md).   

```
    public static void signBucket(S3Presigner presigner, String outpostAccessPointArn, String keyName) {

        try {
            PutObjectRequest objectRequest = PutObjectRequest.builder()
                    .bucket(accessPointArn)
                    .key(keyName)
                    .contentType("text/plain")
                    .build();

            PutObjectPresignRequest presignRequest = PutObjectPresignRequest.builder()
                    .signatureDuration(Duration.ofMinutes(10))
                    .putObjectRequest(objectRequest)
                    .build();

            PresignedPutObjectRequest presignedRequest = presigner.presignPutObject(presignRequest);


            String myURL = presignedRequest.url().toString();
            System.out.println("Presigned URL to upload a file to: " +myURL);
            System.out.println("Which HTTP method must be used when uploading a file: " +
                    presignedRequest.httpRequest().method());

            // Upload content to the S3 on Outposts bucket by using this URL.
            URL url = presignedRequest.url();

            // Create the connection and use it to upload the new object by using the presigned URL.
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoOutput(true);
            connection.setRequestProperty("Content-Type","text/plain");
            connection.setRequestMethod("PUT");
            OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
            out.write("This text was uploaded as an object by using a presigned URL.");
            out.close();

            connection.getResponseCode();
            System.out.println("HTTP response code is " + connection.getResponseCode());

        } catch (S3Exception e) {
            e.getStackTrace();
        } catch (IOException e) {
            e.getStackTrace();
        }
    }
```

------
#### [ Python ]

**SDK para Python (Boto3).**  
Este exemplo mostra como gerar um URL pré-assinado que pode executar uma ação do S3 no Outposts por um tempo limitado. Para obter mais informações, consulte [Uso de URLs pré-assinados para o S3 no Outposts](S3OutpostsPresignedURL.md). Para fazer uma solicitação com o URL, use o pacote `Requests`.  

```
import argparse
import logging
import boto3
from botocore.exceptions import ClientError
import requests

logger = logging.getLogger(__name__)


def generate_presigned_url(s3_client, client_method, method_parameters, expires_in):
    """
    Generate a presigned S3 on Outposts URL that can be used to perform an action.

    :param s3_client: A Boto3 Amazon S3 client.
    :param client_method: The name of the client method that the URL performs.
    :param method_parameters: The parameters of the specified client method.
    :param expires_in: The number of seconds that the presigned URL is valid for.
    :return: The presigned URL.
    """
    try:
        url = s3_client.generate_presigned_url(
            ClientMethod=client_method,
            Params=method_parameters,
            ExpiresIn=expires_in
        )
        logger.info("Got presigned URL: %s", url)
    except ClientError:
        logger.exception(
            "Couldn't get a presigned URL for client method '%s'.", client_method)
        raise
    return url


def usage_demo():
    logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s')

    print('-'*88)
    print("Welcome to the Amazon S3 on Outposts presigned URL demo.")
    print('-'*88)

    parser = argparse.ArgumentParser()
    parser.add_argument('accessPointArn', help="The name of the S3 on Outposts access point ARN.")
    parser.add_argument(
        'key', help="For a GET operation, the key of the object in S3 on Outposts. For a "
                    "PUT operation, the name of a file to upload.")
    parser.add_argument(
        'action', choices=('get', 'put'), help="The action to perform.")
    args = parser.parse_args()

    s3_client = boto3.client('s3')
    client_action = 'get_object' if args.action == 'get' else 'put_object'
    url = generate_presigned_url(
        s3_client, client_action, {'Bucket': args.accessPointArn, 'Key': args.key}, 1000)

    print("Using the Requests package to send a request to the URL.")
    response = None
    if args.action == 'get':
        response = requests.get(url)
    elif args.action == 'put':
        print("Putting data to the URL.")
        try:
            with open(args.key, 'r') as object_file:
                object_text = object_file.read()
            response = requests.put(url, data=object_text)
        except FileNotFoundError:
            print(f"Couldn't find {args.key}. For a PUT operation, the key must be the "
                  f"name of a file that exists on your computer.")

    if response is not None:
        print("Got response:")
        print(f"Status: {response.status_code}")
        print(response.text)

    print('-'*88)


if __name__ == '__main__':
    usage_demo()
```

------