

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用適用於 S3 on OutOutposts 的預先簽章 URL
<a name="S3OutpostsPresignedURL"></a>

若要授予對存放在本機 Outpost 上物件的有限時間存取權限，而不會更新儲存貯體政策，您可以使用預先簽章 URL。使用預先簽章 URL，身為儲存貯體擁有者的您可以與虛擬私有雲端 (VPC) 中的個人共享物件，或授予他們上傳或刪除物件的能力。

當您使用 AWS SDKs或 AWS Command Line Interface (AWS CLI) 建立預先簽章的 URL 時，您可以將 URL 與特定動作建立關聯。您也可以選擇自訂到期時間 (最低 1 秒，最高 7 天) 來授予預先簽章 URL 有限時間的存取權。當您共用預先簽章 URL 時，VPC 中的個人可以執行嵌入 URL 中的動作，如同原始簽章使用者一樣。當 URL 到達到期時間時，該 URL 就會過期且再也無法運作。

## 限制預先簽章的 URL 功能
<a name="S3OutpostsPresignedUrlUploadObjectLimitCapabilities"></a>

預先簽章的 URL 的功能，受到建立它的使用者許可所限制。實質上，預先簽章的 URL 是一種承載符記，可為擁有這些網址的客戶授與存取權。因此，我們建議您妥善保護它們。

**AWS Signature 第 4 版 (SigV4)**  
若要在使用 AWS Signature 第 4 版 (SigV4) 驗證預先簽章的 URL 請求時強制執行特定行為，您可以在儲存貯體政策和存取點政策中使用條件金鑰。例如，您可以建立儲存貯體政策，使用 `s3-outposts:signatureAge` 條件來拒絕任何 `example-outpost-bucket` 儲存貯體中物件上的 Amazon S3 on Outposts 預先簽章 URL 請求 (如果簽章超過 10 分鐘)。若要使用此範例，請以您自己的資訊取代 *`user input placeholders`*。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "Deny a presigned URL request if the signature is more than 10 minutes old",
            "Effect": "Deny",
            "Principal": {"AWS":"444455556666"},
            "Action": "s3-outposts:*",
            "Resource": "arn:aws:s3-outposts:us-east-1:111122223333:outpost/op-01ac5d28a6a232904/bucket/example-outpost-bucket/object/*",
            "Condition": {
                "NumericGreaterThan": {"s3-outposts:signatureAge": 600000},
                "StringEquals": {"s3-outposts:authType": "REST-QUERY-STRING"}
            }
        }
    ]
}
```

------

如需取得可用來強制執行特定行為 (在使用第 4 版簽署程序驗證預先簽章的 URL 請求時) 的條件金鑰和其他政策範例清單，請參閱 [AWS Signature 第 4 版 (SigV4) 身分驗證特定政策金鑰](s3-outposts-bucket-policy-s3-sigv4-conditions.md)。

**網路路徑限制**  
如果您想要限制使用預先簽章 URL 和對特定網路路徑的所有 S3 on Outposts 存取權，您可以撰寫需要特定網路路徑的政策。若要對進行呼叫的 IAM 主體設定限制，您可以使用身分型 AWS Identity and Access Management (IAM) 政策 （例如使用者、群組或角色政策）。若要在 S3 on Outposts 資源上設定的限制，您可以使以資源型政策 (例如儲存貯體和存取點政策)。

IAM 主體的網路路徑限制需要這些憑證的使用者從指定的網路發出請求。儲存貯體或存取點上的限制要求所有對該資源的請求都來自指定網路。這些限制也適用於預先簽章的 URL 案例之外。

您使用的 IAM 全域條件取決於端點類型。如果您正在使用 S3 on Outposts 的公有端點，請使用 `aws:SourceIp`。如果您正在使用 S3 on Outposts 的 VPC 端點，請使用 `aws:SourceVpc` 或 `aws:SourceVpce`。

下列 IAM 政策陳述式要求委託人 AWS 只能從指定的網路範圍存取 。由於此政策聲明，所有存取均必須源自該範圍。這包含某人使用 S3 on Outposts 預先簽章 URL 的情況。若要使用此範例，請以您自己的資訊取代 *`user input placeholders`*。

```
{
    "Sid": "NetworkRestrictionForIAMPrincipal",
    "Effect": "Deny",
    "Action": "*",
    "Resource": "*",
    "Condition": {
        "NotIpAddressIfExists": {"aws:SourceIp": "IP-address-range"},
        "BoolIfExists": {"aws:ViaAWSService": "false"}
    }
}
```

如需使用 `aws:SourceIP` AWS 全域條件金鑰將對 S3 on Outposts 儲存貯體的存取限制在特定網路範圍的範例儲存貯體政策，請參閱 [使用 S3 on Outposts 設定 IAM](S3OutpostsIAM.md)。

## 誰可以建立預先簽章的 URL
<a name="S3Outpostswho-presigned-url"></a>

任何具備有效安全憑證的使用者，均可建立預先簽章的 URL。但為了讓 VPC 中的使用者能順利存取物件，預先簽章的 URL 必須由有權執行預先簽章的 URL 做為基礎之操作的人員來建立。

您可以使用下列憑證來建立預先簽章 URL：
+ **IAM 執行個體設定檔** - 有效期限最長 6 小時。
+ **AWS Security Token Service** - 以 AWS 帳戶 根使用者或 IAM 使用者憑證等永久憑證簽章時，有效期限最長 36 小時。
+ **IAM 使用者** – 當您使用 AWS Signature 第 4 版時，有效期最長為 7 天。

  若要建立有效期限最長 7 天的預先簽章 URL，請先將 IAM 使用者憑證 (存取金鑰和私密金鑰) 委派給您在使用的 SDK。然後，使用 AWS Signature 第 4 版產生預先簽章的 URL。

**注意**  
如果使用暫時字符建立了預先簽章的 URL，則 URL 會在字符過期時過期，即使您使用較晚的過期時間建立 URL 亦然。
由於預先簽章 URL 會將 S3 on Outposts 儲存貯體的存取權授予擁有 URL 的任何人，因此我們建議您妥善保護這些 URL。如需保護預先簽章的 URL 的詳細資訊，請參閱[限制預先簽章的 URL 功能](#S3OutpostsPresignedUrlUploadObjectLimitCapabilities)。

## S3 on Outposts 何時檢查預先簽章的 URL 中的到期日期和時間？
<a name="S3Outpostspresigned-url-when-checked"></a>

S3 on Outposts 會在發出 HTTP 請求時，檢查已簽署 URL 的到期日期和時間。例如，如果用戶端在到期前一刻才開始下載大型檔案，則即使在下載期間過期了，下載也會繼續。然而，如果連線中斷並且用戶端在到期時間過後嘗試重新啟動下載，則下載會失敗。

如需使用預先簽章 URL 來共享或上傳物件的詳細資訊，請參閱下列主題。

**Topics**
+ [限制預先簽章的 URL 功能](#S3OutpostsPresignedUrlUploadObjectLimitCapabilities)
+ [誰可以建立預先簽章的 URL](#S3Outpostswho-presigned-url)
+ [S3 on Outposts 何時檢查預先簽章的 URL 中的到期日期和時間？](#S3Outpostspresigned-url-when-checked)
+ [使用預先簽章的 URL 來共用物件](S3OutpostsShareObjectPresignedURL.md)
+ [產生預先簽章 URL 以將物件上傳至 S3 on Outposts 儲存貯體](S3OutpostsPresignedUrlUploadObject.md)

# 使用預先簽章的 URL 來共用物件
<a name="S3OutpostsShareObjectPresignedURL"></a>

若要授予對存放在本機 Outpost 上物件的有限時間存取權限，而不會更新儲存貯體政策，您可以使用預先簽章 URL。使用預先簽章 URL，身為儲存貯體擁有者的您可以與虛擬私有雲端 (VPC) 中的個人共享物件，或授予他們上傳或刪除物件的能力。

當您使用 AWS SDKs或 AWS Command Line Interface (AWS CLI) 建立預先簽章的 URL 時，您可以將 URL 與特定動作建立關聯。您也可以選擇自訂到期時間 (最低 1 秒，最高 7 天) 來授予預先簽章 URL 有限時間的存取權。當您共用預先簽章 URL 時，VPC 中的個人可以執行嵌入 URL 中的動作，如同原始簽章使用者一樣。當 URL 到達到期時間時，該 URL 就會過期且再也無法運作。



當您建立預先簽章 URL 時，必須提供安全憑證，然後指定下列項目：
+ 適用於 Amazon S3 on Outposts 儲存貯體的存取點 Amazon Resource Name (ARN)
+ 物件索引鍵
+ HTTP 方法 (`GET` 用於下載物件)
+ 過期日期和時間

預先簽章 URL 僅在指定的期間內有效。也就是說，您必須在到期日期和時間之前開始 URL 所允許的操作。您可以多次使用預先簽章 URL，直到到期日期和時間為止。如果使用暫時字符建立了預先簽章的 URL，那麼 URL 會在字符過期時過期，即使您使用較晚的過期時間建立 URL 亦然。

虛擬私有雲端 (VPC) 中可存取預先簽章 URL 的使用者可以存取物件。例如，若儲存貯體中有一段影片且儲存貯體與物件皆為私有，即可透過產生預先簽章的 URL 來與其他人分享這段影片。由於預先簽章 URL 會將 S3 on Outposts 儲存貯體的存取權授予擁有 URL 的任何人，因此我們建議您妥善保護這些 URL。如需有關保護預先簽署 URL 的詳細資訊，請參閱[限制預先簽章的 URL 功能](S3OutpostsPresignedURL.md#S3OutpostsPresignedUrlUploadObjectLimitCapabilities)。

任何具備有效安全憑證的使用者，均可建立預先簽章的 URL。然而，只有具備許可執行作為預先簽章 URL 基礎操作的人員，才能建立預先簽章 URL。如需詳細資訊，請參閱[誰可以建立預先簽章的 URL](S3OutpostsPresignedURL.md#S3Outpostswho-presigned-url)。

您可以使用 AWS SDK 與 AWS CLI來產生預先簽章 URL，以在 S3 on Outposts 儲存貯體中共享物件。如需詳細資訊，請參閱下列範例。

## 使用 AWS SDKs
<a name="S3OutpostsShareObjectPreSignedURLSDK"></a>

您可以使用 AWS SDKs 來產生可提供給其他人的預先簽章 URL，以便他們可以擷取物件。

**注意**  
當您使用 AWS SDKs產生預先簽章的 URL 時，預先簽章 URL 的過期時間上限為從建立時間起算 7 天。

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

**Example**  
以下範例會產生預先簽章的 URL，您可以將其提供給其他人，讓他們可以從 S3 on Outposts 儲存貯體擷取物件。如需詳細資訊，請參閱[使用適用於 S3 on OutOutposts 的預先簽章 URL](S3OutpostsPresignedURL.md)。若要使用此範例，請以您自己的資訊取代 *`user input placeholders`*。  

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.HttpMethod;
import com.amazonaws.SdkClientException;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest;

import java.io.IOException;
import java.net.URL;
import java.time.Instant;

public class GeneratePresignedURL {

    public static void main(String[] args) throws IOException {
        Regions clientRegion = Regions.DEFAULT_REGION;
        String accessPointArn = "*** access point ARN ***";
        String objectKey = "*** object key ***";

        try {
            AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                    .withRegion(clientRegion)
                    .withCredentials(new ProfileCredentialsProvider())
                    .build();

            // Set the presigned URL to expire after one hour.
            java.util.Date expiration = new java.util.Date();
            long expTimeMillis = Instant.now().toEpochMilli();
            expTimeMillis += 1000 * 60 * 60;
            expiration.setTime(expTimeMillis);

            // Generate the presigned URL.
            System.out.println("Generating pre-signed URL.");
            GeneratePresignedUrlRequest generatePresignedUrlRequest =
                    new GeneratePresignedUrlRequest(accessPointArn, objectKey)
                            .withMethod(HttpMethod.GET)
                            .withExpiration(expiration);
            URL url = s3Client.generatePresignedUrl(generatePresignedUrlRequest);

            System.out.println("Pre-Signed URL: " + url.toString());
        } catch (AmazonServiceException e) {
            // The call was transmitted successfully, but Amazon S3 couldn't process 
            // it, so it returned an error response.
            e.printStackTrace();
        } catch (SdkClientException e) {
            // Amazon S3 couldn't be contacted for a response, or the client
            // couldn't parse the response from Amazon S3.
            e.printStackTrace();
        }
    }
}
```

------
#### [ .NET ]

**Example**  
以下範例會產生預先簽章的 URL，您可以將其提供給其他人，讓他們可以從 S3 on Outposts 儲存貯體擷取物件。如需詳細資訊，請參閱[使用適用於 S3 on OutOutposts 的預先簽章 URL](S3OutpostsPresignedURL.md)。若要使用此範例，請以您自己的資訊取代 *`user input placeholders`*。  

```
using Amazon;
using Amazon.S3;
using Amazon.S3.Model;
using System;

namespace Amazon.DocSamples.S3
{
    class GenPresignedURLTest
    {
        private const string accessPointArn = "*** access point ARN ***"; 
        private const string objectKey = "*** object key ***";
        // Specify how long the presigned URL lasts, in hours.
        private const double timeoutDuration = 12;
        // Specify your bucket Region (an example Region is shown).
        private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USWest2;
        private static IAmazonS3 s3Client;

        public static void Main()
        {
            s3Client = new AmazonS3Client(bucketRegion);
            string urlString = GeneratePreSignedURL(timeoutDuration);
        }
        static string GeneratePreSignedURL(double duration)
        {
            string urlString = "";
            try
            {
                GetPreSignedUrlRequest request1 = new GetPreSignedUrlRequest
                {
                    BucketName = accessPointArn,
                    Key = objectKey,
                    Expires = DateTime.UtcNow.AddHours(duration)
                };
                urlString = s3Client.GetPreSignedURL(request1);
            }
            catch (AmazonS3Exception e)
            {
                Console.WriteLine("Error encountered on server. Message:'{0}' when writing an object", e.Message);
            }
            catch (Exception e)
            {
                Console.WriteLine("Unknown encountered on server. Message:'{0}' when writing an object", e.Message);
            }
            return urlString;
        }
    }
}
```

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

下列範例使用了 SDK for Python (Boto3) 來產生預先簽章的 URL 以共用物件。例如，使用 Boto3 用戶端和 `generate_presigned_url` 函數來產生允許您 `GET` 物件的預先簽章的 URL。

```
import boto3
    url = boto3.client('s3').generate_presigned_url(
    ClientMethod='get_object', 
    Params={'Bucket': 'ACCESS_POINT_ARN', 'Key': 'OBJECT_KEY'},
    ExpiresIn=3600)
```

如需有關使用 SDK for Python (Boto3) 產生預先簽章的 URL 的詳細資訊，請參閱《*適用於 Python (Boto) 的 AWS SDK API 參考*》中的「[Python](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html#S3.Client.generate_presigned_url)」。

------

## 使用 AWS CLI
<a name="S3OutpostsShareObjectPresignedCLI"></a>

下列範例 AWS CLI 命令會為 S3 on Outposts 儲存貯體產生預先簽章的 URL。若要使用此範例，請以您自己的資訊取代 *`user input placeholders`*。

**注意**  
當您使用 AWS CLI 產生預先簽章的 URL 時，預先簽章的 URL 最長過期時間為建立後 7 天。

```
aws s3 presign s3://arn:aws:s3-outposts:us-east-1:111122223333:outpost/op-01ac5d28a6a232904/accesspoint/example-outpost-access-point/mydoc.txt --expires-in 604800
```

如需詳細資訊，請參閱《*AWS CLI 命令參考*》中的 [presign](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3/presign.html)。

# 產生預先簽章 URL 以將物件上傳至 S3 on Outposts 儲存貯體
<a name="S3OutpostsPresignedUrlUploadObject"></a>

若要授予對存放在本機 Outpost 上物件的有限時間存取權限，而不會更新儲存貯體政策，您可以使用預先簽章 URL。使用預先簽章 URL，身為儲存貯體擁有者的您可以與虛擬私有雲端 (VPC) 中的個人共享物件，或授予他們上傳或刪除物件的能力。

當您使用 AWS SDKs或 AWS Command Line Interface (AWS CLI) 建立預先簽章的 URL 時，您可以將 URL 與特定動作建立關聯。您也可以選擇自訂到期時間 (最低 1 秒，最高 7 天) 來授予預先簽章 URL 有限時間的存取權。當您共用預先簽章 URL 時，VPC 中的個人可以執行嵌入 URL 中的動作，如同原始簽章使用者一樣。當 URL 到達到期時間時，該 URL 就會過期且再也無法運作。

當您建立預先簽章 URL 時，必須提供安全憑證，然後指定下列項目：
+ 適用於 Amazon S3 on Outposts 儲存貯體的存取點 Amazon Resource Name (ARN)
+ 物件索引鍵
+ HTTP 方法 (`PUT` 用於上傳物件)
+ 過期日期和時間

預先簽章 URL 僅在指定的期間內有效。也就是說，您必須在到期日期和時間之前開始 URL 所允許的操作。您可以多次使用預先簽章 URL，直到到期日期和時間為止。如果使用暫時字符建立了預先簽章的 URL，那麼 URL 會在字符過期時過期，即使您使用較晚的過期時間建立 URL 亦然。

如果預先簽章的 URL 所允許的動作包含多個步驟 (例如分段上傳)，則您必須在到期之前開始所有步驟。如果 S3 on Outposts 嘗試以過期 URL 開始步驟時，您會收到錯誤。

虛擬私有雲端 (VPC) 中可存取預先簽章 URL 的使用者可以上傳物件。例如，VPC 中具有可存取預先簽章 URL 的使用者可以將物件上傳到您的儲存貯體。由於預先簽章 URL 會將 S3 on Outposts 儲存貯體的存取權授予 VPC 中擁有預先簽章 URL 存取權的任何使用者，因此我們建議您妥善保護這些 URL。如需有關保護預先簽署 URL 的詳細資訊，請參閱[限制預先簽章的 URL 功能](S3OutpostsPresignedURL.md#S3OutpostsPresignedUrlUploadObjectLimitCapabilities)。

任何具備有效安全憑證的使用者，均可建立預先簽章的 URL。然而，只有具備許可執行作為預先簽章 URL 基礎操作的人員，才能建立預先簽章 URL。如需詳細資訊，請參閱[誰可以建立預先簽章的 URL](S3OutpostsPresignedURL.md#S3Outpostswho-presigned-url)。

## 使用 AWS SDKs為 S3 on Outposts 物件操作產生預先簽章的 URL
<a name="s3-outposts-presigned-urls-upload-examples"></a>

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

**適用於 Java 2.x 的 SDK**  
此範例顯示如何產生可以於限定時間內用來將物件上傳至 S3 on Outposts 儲存貯體的預先簽章 URL。如需詳細資訊，請參閱[使用適用於 S3 on OutOutposts 的預先簽章 URL](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 ]

**適用於 Python 的 SDK (Boto3)**  
此範例顯示如何產生可於限定時間內執行 S3 on Outposts 動作的預先簽章 URL。如需詳細資訊，請參閱[使用適用於 S3 on OutOutposts 的預先簽章 URL](S3OutpostsPresignedURL.md)。若要使用 URL 提出請求，請使用 `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()
```

------