

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

# 使用 IAM 使用者暫時性登入資料提出請求
<a name="AuthUsingTempSessionToken"></a>

 AWS 帳戶 或 IAM 使用者可以請求臨時安全登入資料，並使用它們將已驗證的請求傳送至 Amazon S3。本節提供的範例是如何使用 適用於 Java 的 AWS SDK、.NET 與 PHP 來取得暫時性安全登入資料，然後使用這些登入資料來為對 Amazon S3 的請求進行驗證。

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

IAM 使用者或 AWS 帳戶 可以使用 請求臨時安全登入資料 （請參閱 [提出要求](MakingRequests.md)) 適用於 Java 的 AWS SDK ，並使用它們來存取 Amazon S3。這些登入資料會在指定的工作階段使用期限之後到期。

工作階段使用期限預設是一小時。如果您使用 IAM 使用者登入資料，可以在請求暫時性安全登入資料時，為角色指定持續時間，從 15 分鐘到最大的工作階段持續時間。如需暫時安全登入資料的詳細資訊，請參閱《*IAM 使用者指南*》中的[暫時安全登入資料](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html)。如需提出請求的詳細資訊，請參閱[提出要求](MakingRequests.md)。

**取得暫時性安全登入資料並存取 Amazon S3**

1. 建立 `AWSSecurityTokenService` 類別的執行個體。

1. 呼叫安全性字符服務 (STS) 用戶端的 `assumeRole()` 方法，擷取所需角色的臨時安全登入資料。

1. 將暫時安全登入資料封裝至 `BasicSessionCredentials` 物件。您可以使用此物件，將暫時性安全登入資料提供給 Amazon S3 用戶端。

1. 使用暫時性安全登入資料建立 `AmazonS3Client` 類別的執行個體。您可以使用此用戶端，將請求傳送給 Amazon S3。如果使用過期的登入資料傳送請求，Amazon S3 將會傳回錯誤。

**注意**  
如果您使用 AWS 帳戶 安全登入資料來取得暫時性安全登入資料，則暫時性登入資料只會作用一個小時。只有在您使用 IAM 使用者登入資料來請求工作階段時，才能指定工作階段使用期限。

下列範例會列出所指定儲存貯體中的一組物件金鑰。此範例會取得工作階段的臨時安全登入資料，然後使用這些登入資料將透過身分驗證的請求傳送給 Amazon S3。

如果您想要使用 IAM 使用者憑證來測試範例，則必須透過 AWS 帳戶建立 IAM 使用者。如需如何建立 IAM 使用者的詳細資訊，請參閱《IAM 使用者指南》**中的[建立第一個 IAM 使用者與管理員群組](https://docs.aws.amazon.com/IAM/latest/UserGuide/getting-started_create-admin-group.html)。

如需建立和測試工作範例的說明，請參閱《 適用於 Java 的 AWS SDK 開發人員指南》中的[入門](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/getting-started.html)。

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.SdkClientException;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicSessionCredentials;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.ObjectListing;
import com.amazonaws.services.securitytoken.AWSSecurityTokenService;
import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClientBuilder;
import com.amazonaws.services.securitytoken.model.AssumeRoleRequest;
import com.amazonaws.services.securitytoken.model.AssumeRoleResult;
import com.amazonaws.services.securitytoken.model.Credentials;

public class MakingRequestsWithIAMTempCredentials {
    public static void main(String[] args) {
        String clientRegion = "*** Client region ***";
        String roleARN = "*** ARN for role to be assumed ***";
        String roleSessionName = "*** Role session name ***";
        String bucketName = "*** Bucket name ***";

        try {
            // Creating the STS client is part of your trusted code. It has
            // the security credentials you use to obtain temporary security credentials.
            AWSSecurityTokenService stsClient = AWSSecurityTokenServiceClientBuilder.standard()
                    .withCredentials(new ProfileCredentialsProvider())
                    .withRegion(clientRegion)
                    .build();

            // Obtain credentials for the IAM role. Note that you cannot assume the role of
            // an AWS root account;
            // Amazon S3 will deny access. You must use credentials for an IAM user or an
            // IAM role.
            AssumeRoleRequest roleRequest = new AssumeRoleRequest()
                    .withRoleArn(roleARN)
                    .withRoleSessionName(roleSessionName);
            AssumeRoleResult roleResponse = stsClient.assumeRole(roleRequest);
            Credentials sessionCredentials = roleResponse.getCredentials();

            // Create a BasicSessionCredentials object that contains the credentials you
            // just retrieved.
            BasicSessionCredentials awsCredentials = new BasicSessionCredentials(
                    sessionCredentials.getAccessKeyId(),
                    sessionCredentials.getSecretAccessKey(),
                    sessionCredentials.getSessionToken());

            // Provide temporary security credentials so that the Amazon S3 client
            // can send authenticated requests to Amazon S3. You create the client
            // using the sessionCredentials object.
            AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                    .withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
                    .withRegion(clientRegion)
                    .build();

            // Verify that assuming the role worked and the permissions are set correctly
            // by getting a set of object keys from the bucket.
            ObjectListing objects = s3Client.listObjects(bucketName);
            System.out.println("No. of Objects: " + objects.getObjectSummaries().size());
        } 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 ]

IAM 使用者或 AWS 帳戶 可以使用 請求臨時安全登入資料 適用於 .NET 的 AWS SDK ，並使用它們來存取 Amazon S3。這些登入資料會在工作階段使用期限之後到期。

工作階段使用期限預設是一小時。如果您使用 IAM 使用者登入資料，可以在請求暫時性安全登入資料時，為角色指定持續時間，從 15 分鐘到最大的工作階段持續時間。如需暫時安全登入資料的詳細資訊，請參閱《*IAM 使用者指南*》中的[暫時安全登入資料](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html)。如需提出請求的詳細資訊，請參閱[提出要求](MakingRequests.md)。

**取得暫時性安全登入資料並存取 Amazon S3**

1. 建立 AWS Security Token Service 用戶端的執行個體 `AmazonSecurityTokenServiceClient`。

1. 呼叫您在上一個步驟中所建立之 STS 用戶端的 `GetSessionToken` 方法，以啟動工作階段。您可以使用 `GetSessionTokenRequest` 物件，將工作階段資訊提供給此方法。

   此方法會傳回暫時性安全登入資料。

1. 將暫時安全登入資料封裝至 `SessionAWSCredentials` 物件執行個體。您可以使用此物件，將暫時性安全登入資料提供給 Amazon S3 用戶端。

1. 傳入暫時性安全登入資料，以建立 `AmazonS3Client` 類別執行個體。您可以使用此用戶端，將請求傳送給 Amazon S3。如果使用過期的登入資料傳送請求，Amazon S3 會傳回錯誤。

**注意**  
如果您使用 AWS 帳戶 安全登入資料來取得暫時性安全登入資料，則該些登入資料只會作用一個小時。您只能在使用 IAM 使用者登入資料請求工作階段時，指定工作階段使用期限。

下列 C\# 範例會列出指定儲存貯體中的物件金鑰。為了方便說明，該範例會取得預設一小時工作階段的暫時性安全登入資料，然後使用這些登入資料將透過身分驗證的請求傳送給 Amazon S3。

如果您想要使用 IAM 使用者憑證來測試範例，則必須透過 AWS 帳戶建立 IAM 使用者。如需如何建立 IAM 使用者的詳細資訊，請參閱《IAM 使用者指南》**中的[建立第一個 IAM 使用者與管理員群組](https://docs.aws.amazon.com/IAM/latest/UserGuide/getting-started_create-admin-group.html)。如需提出請求的詳細資訊，請參閱[提出要求](MakingRequests.md)。

 如需有關設定和執行程式碼範例的資訊，請參閱《[適用於 .NET 的 AWS SDK 開發人員指南》中的適用於 .NET 的 SDK 入門](https://docs.aws.amazon.com/sdk-for-net/latest/developer-guide/net-dg-setup.html)。 *AWS *

```
using Amazon;
using Amazon.Runtime;
using Amazon.S3;
using Amazon.S3.Model;
using Amazon.SecurityToken;
using Amazon.SecurityToken.Model;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Amazon.DocSamples.S3
{
    class TempCredExplicitSessionStartTest
    {
        private const string bucketName = "*** bucket name ***";
        // Specify your bucket region (an example region is shown).
        private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USWest2;
        private static IAmazonS3 s3Client;
        public static void Main()
        {
            ListObjectsAsync().Wait();
        }

        private static async Task ListObjectsAsync()
        {
            try
            {
                // Credentials use the default AWS SDK for .NET credential search chain. 
                // On local development machines, this is your default profile.
                Console.WriteLine("Listing objects stored in a bucket");
                SessionAWSCredentials tempCredentials = await GetTemporaryCredentialsAsync();

                // Create a client by providing temporary security credentials.
                using (s3Client = new AmazonS3Client(tempCredentials, bucketRegion))
                {
                    var listObjectRequest = new ListObjectsRequest
                    {
                        BucketName = bucketName
                    };
                    // Send request to Amazon S3.
                    ListObjectsResponse response = await s3Client.ListObjectsAsync(listObjectRequest);
                    List<S3Object> objects = response.S3Objects;
                    Console.WriteLine("Object count = {0}", objects.Count);
                }
            }
            catch (AmazonS3Exception s3Exception)
            {
                Console.WriteLine(s3Exception.Message, s3Exception.InnerException);
            }
            catch (AmazonSecurityTokenServiceException stsException)
            {
                Console.WriteLine(stsException.Message, stsException.InnerException);
            }
        }

        private static async Task<SessionAWSCredentials> GetTemporaryCredentialsAsync()
        {
            using (var stsClient = new AmazonSecurityTokenServiceClient())
            {
                var getSessionTokenRequest = new GetSessionTokenRequest
                {
                    DurationSeconds = 7200 // seconds
                };

                GetSessionTokenResponse sessionTokenResponse =
                              await stsClient.GetSessionTokenAsync(getSessionTokenRequest);

                Credentials credentials = sessionTokenResponse.Credentials;

                var sessionCredentials =
                    new SessionAWSCredentials(credentials.AccessKeyId,
                                              credentials.SecretAccessKey,
                                              credentials.SessionToken);
                return sessionCredentials;
            }
        }
    }
}
```

------
#### [ PHP ]

如需適用於 Ruby 的 AWS SDK API 的詳細資訊，請前往[AWS 適用於 Ruby 的 SDK - 第 2 版](https://docs.aws.amazon.com/sdkforruby/api/index.html)。

IAM 使用者或 AWS 帳戶 可以使用 第 3 版請求臨時安全登入資料 適用於 PHP 的 AWS SDK。然後，可以使用該暫時性登入資料來存取 Amazon S3。該登入資料會在工作階段使用期限到期時到期。

工作階段使用期限預設是一小時。如果您使用 IAM 使用者登入資料，可以在請求暫時性安全登入資料時，為角色指定持續時間，從 15 分鐘到最大的工作階段持續時間。如需暫時安全登入資料的詳細資訊，請參閱《*IAM 使用者指南*》中的[暫時安全登入資料](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html)。如需提出請求的詳細資訊，請參閱[提出要求](MakingRequests.md)。

**注意**  
如果您使用 AWS 帳戶 安全登入資料來取得暫時性安全登入資料，則暫時性安全登入資料只會作用一個小時。只有在您使用 IAM 使用者登入資料來請求工作階段時，才能指定工作階段使用期限。

**Example**  
下列 PHP 範例會使用暫時性安全登入資料來列出指定儲存貯體中的物件金鑰。此範例會取得預設一小時工作階段的暫時性安全登入資料，然後使用這些登入資料將透過身分驗證的請求傳送給 Amazon S3。如需適用於 Ruby 的 AWS SDK API 的詳細資訊，請前往[AWS 適用於 Ruby 的 SDK - 第 2 版](https://docs.aws.amazon.com/sdkforruby/api/index.html)。  
如果您想要使用 IAM 使用者憑證來測試範例，則需要透過 AWS 帳戶建立 IAM 使用者。如需如何建立 IAM 使用者的資訊，請參閱《IAM 使用者指南》**中的[建立第一個 IAM 使用者與管理員群組](https://docs.aws.amazon.com/IAM/latest/UserGuide/getting-started_create-admin-group.html)。如需使用 IAM 使用者登入資料要求工作階段時設定工作階段使用期限的範例，請參閱「[使用 IAM 使用者暫時性登入資料提出請求](#AuthUsingTempSessionToken)」。  

```
 require 'vendor/autoload.php';

use Aws\S3\Exception\S3Exception;
use Aws\S3\S3Client;
use Aws\Sts\StsClient;

$bucket = '*** Your Bucket Name ***';

$sts = new StsClient([
    'version' => 'latest',
    'region' => 'us-east-1'
]);

$sessionToken = $sts->getSessionToken();

$s3 = new S3Client([
    'region' => 'us-east-1',
    'version' => 'latest',
    'credentials' => [
        'key'    => $sessionToken['Credentials']['AccessKeyId'],
        'secret' => $sessionToken['Credentials']['SecretAccessKey'],
        'token'  => $sessionToken['Credentials']['SessionToken']
    ]
]);

$result = $s3->listBuckets();

try {
    // Retrieve a paginator for listing objects.
    $objects = $s3->getPaginator('ListObjects', [
        'Bucket' => $bucket
    ]);

    echo "Keys retrieved!" . PHP_EOL;

    // List objects
    foreach ($objects as $object) {
        echo $object['Key'] . PHP_EOL;
    }
} catch (S3Exception $e) {
    echo $e->getMessage() . PHP_EOL;
}
```

------
#### [ Ruby ]

IAM 使用者或 AWS 帳戶 可以使用 請求臨時安全登入資料 適用於 Ruby 的 AWS SDK ，並使用它們來存取 Amazon S3。這些登入資料會在工作階段使用期限之後到期。

工作階段使用期限預設是一小時。如果您使用 IAM 使用者登入資料，可以在請求暫時性安全登入資料時，為角色指定持續時間，從 15 分鐘到最大的工作階段持續時間。如需暫時安全登入資料的詳細資訊，請參閱《*IAM 使用者指南*》中的[暫時安全登入資料](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html)。如需提出請求的詳細資訊，請參閱[提出要求](MakingRequests.md)。

**注意**  
如果您使用 AWS 帳戶 安全登入資料來取得暫時性安全登入資料，則暫時性安全登入資料只會作用一個小時。只有在您使用 IAM 使用者登入資料請求工作階段時，才能指定工作階段使用期限。

下列 Ruby 範例會建立暫時使用者有一小時的時間可列出指定儲存貯體中的項目。若要使用此範例，您必須擁有 AWS 具有必要許可的登入資料，才能建立新的 AWS Security Token Service (AWS STS) 用戶端，並列出 Amazon S3 儲存貯體。

```
# Prerequisites:
# - A user in AWS Identity and Access Management (IAM). This user must
#   be able to assume the following IAM role. You must run this code example
#   within the context of this user.
# - An existing role in IAM that allows all of the Amazon S3 actions for all of the
#   resources in this code example. This role must also trust the preceding IAM user.
# - An existing S3 bucket.

require 'aws-sdk-core'
require 'aws-sdk-s3'
require 'aws-sdk-iam'

# Checks whether a user exists in IAM.
#
# @param iam [Aws::IAM::Client] An initialized IAM client.
# @param user_name [String] The user's name.
# @return [Boolean] true if the user exists; otherwise, false.
# @example
#   iam_client = Aws::IAM::Client.new(region: 'us-west-2')
#   exit 1 unless user_exists?(iam_client, 'my-user')
def user_exists?(iam_client, user_name)
  response = iam_client.get_user(user_name: user_name)
  return true if response.user.user_name
rescue Aws::IAM::Errors::NoSuchEntity
  # User doesn't exist.
rescue StandardError => e
  puts 'Error while determining whether the user ' \
    "'#{user_name}' exists: #{e.message}"
end

# Creates a user in IAM.
#
# @param iam_client [Aws::IAM::Client] An initialized IAM client.
# @param user_name [String] The user's name.
# @return [AWS:IAM::Types::User] The new user.
# @example
#   iam_client = Aws::IAM::Client.new(region: 'us-west-2')
#   user = create_user(iam_client, 'my-user')
#   exit 1 unless user.user_name
def create_user(iam_client, user_name)
  response = iam_client.create_user(user_name: user_name)
  response.user
rescue StandardError => e
  puts "Error while creating the user '#{user_name}': #{e.message}"
end

# Gets a user in IAM.
#
# @param iam_client [Aws::IAM::Client] An initialized IAM client.
# @param user_name [String] The user's name.
# @return [AWS:IAM::Types::User] The existing user.
# @example
#   iam_client = Aws::IAM::Client.new(region: 'us-west-2')
#   user = get_user(iam_client, 'my-user')
#   exit 1 unless user.user_name
def get_user(iam_client, user_name)
  response = iam_client.get_user(user_name: user_name)
  response.user
rescue StandardError => e
  puts "Error while getting the user '#{user_name}': #{e.message}"
end

# Checks whether a role exists in IAM.
#
# @param iam_client [Aws::IAM::Client] An initialized IAM client.
# @param role_name [String] The role's name.
# @return [Boolean] true if the role exists; otherwise, false.
# @example
#   iam_client = Aws::IAM::Client.new(region: 'us-west-2')
#   exit 1 unless role_exists?(iam_client, 'my-role')
def role_exists?(iam_client, role_name)
  response = iam_client.get_role(role_name: role_name)
  return true if response.role.role_name
rescue StandardError => e
  puts 'Error while determining whether the role ' \
    "'#{role_name}' exists: #{e.message}"
end

# Gets credentials for a role in IAM.
#
# @param sts_client [Aws::STS::Client] An initialized AWS STS client.
# @param role_arn [String] The role's Amazon Resource Name (ARN).
# @param role_session_name [String] A name for this role's session.
# @param duration_seconds [Integer] The number of seconds this session is valid.
# @return [AWS::AssumeRoleCredentials] The credentials.
# @example
#   sts_client = Aws::STS::Client.new(region: 'us-west-2')
#   credentials = get_credentials(
#     sts_client,
#     'arn:aws:iam::123456789012:role/AmazonS3ReadOnly',
#     'ReadAmazonS3Bucket',
#     3600
#   )
#   exit 1 if credentials.nil?
def get_credentials(sts_client, role_arn, role_session_name, duration_seconds)
  Aws::AssumeRoleCredentials.new(
    client: sts_client,
    role_arn: role_arn,
    role_session_name: role_session_name,
    duration_seconds: duration_seconds
  )
rescue StandardError => e
  puts "Error while getting credentials: #{e.message}"
end

# Checks whether a bucket exists in Amazon S3.
#
# @param s3_client [Aws::S3::Client] An initialized Amazon S3 client.
# @param bucket_name [String] The name of the bucket.
# @return [Boolean] true if the bucket exists; otherwise, false.
# @example
#   s3_client = Aws::S3::Client.new(region: 'us-west-2')
#   exit 1 unless bucket_exists?(s3_client, 'amzn-s3-demo-bucket')
def bucket_exists?(s3_client, bucket_name)
  response = s3_client.list_buckets
  response.buckets.each do |bucket|
    return true if bucket.name == bucket_name
  end
rescue StandardError => e
  puts "Error while checking whether the bucket '#{bucket_name}' " \
    "exists: #{e.message}"
end

# Lists the keys and ETags for the objects in an Amazon S3 bucket.
#
# @param s3_client [Aws::S3::Client] An initialized Amazon S3 client.
# @param bucket_name [String] The bucket's name.
# @return [Boolean] true if the objects were listed; otherwise, false.
# @example
#   s3_client = Aws::S3::Client.new(region: 'us-west-2')
#   exit 1 unless list_objects_in_bucket?(s3_client, 'amzn-s3-demo-bucket')
def list_objects_in_bucket?(s3_client, bucket_name)
  puts "Accessing the contents of the bucket named '#{bucket_name}'..."
  response = s3_client.list_objects_v2(
    bucket: bucket_name,
    max_keys: 50
  )

  if response.count.positive?
    puts "Contents of the bucket named '#{bucket_name}' (first 50 objects):"
    puts 'Name => ETag'
    response.contents.each do |obj|
      puts "#{obj.key} => #{obj.etag}"
    end
  else
    puts "No objects in the bucket named '#{bucket_name}'."
  end
  true
rescue StandardError => e
  puts "Error while accessing the bucket named '#{bucket_name}': #{e.message}"
end
```

------