使用聯合身分使用者暫時登入資料提出要求 - Amazon Simple Storage Service

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

使用聯合身分使用者暫時登入資料提出要求

您可以要求臨時安全登入資料,並將其提供給需要存取 AWS 資源的同盟使用者或應用程式。本節提供如何使用 AWS SDK 取得聯合身分使用者或應用程式的臨時安全登入資料,以及如何使用這些登入資料將經過驗證的請求傳送至 Amazon S3 的範例。如需可用 AWS SDK 的清單,請參閱範例程式碼和程式庫

注意

IAM 使用者 AWS 帳戶 和 IAM 使用者都可以要求聯合身分使用者的臨時安全登入資料。不過,為了提高安全,只有具有必要許可的 IAM 使用者才應該請求這些暫時登入資料,確保聯合身分使用者善加利用請求 IAM 使用者的許可。在一些應用程式中,您可能會發現一些適合建立 IAM 的使用者,其具有唯一目的為將暫時安全登入資料授予聯合身分使用者與應用程式的特定許可。

Java

您可以為同盟使用者和應用程式提供臨時安全登入資料,以便他們傳送經過驗證的要求以存取您的 AWS 資源。請求這些暫時登入資料時,您必須提供使用者名稱,以及說明您想要授予之資源許可的 IAM 原則。工作階段使用期限預設是一小時。要求聯合身分使用者與應用程式的暫時安全登入資料時,您可以明確地設定不同的持續時間值。

注意

在請求用於聯合身分使用者與應用程式得暫時安全登入資料時,為了提高安全,我們建議您使用專用 IAM 使用者,只進行有必要的存取許可。您所建立暫時使用者的許可絕不可高於已請求暫時安全登入資料的 IAM 使用者。如需詳細資訊,請參閱 AWS Identity and Access Management 常見問答集

為提供安全登入資料和傳送經過驗證的要求以存取資源,請執行以下動作:

  • 建立 AWSSecurityTokenServiceClient 類別的執行個體。

  • 透過呼叫安全字符服務 (STS) 用戶端的 getFederationToken() 方法,開始工作階段。請您提供工作階段資訊,包括您要連線至暫時性登入資料的使用者名稱與 IAM 原則。您可以提供選用的工作階段持續時間。此方法會傳回暫時安全登入資料。

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

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

此範例會列出指定 S3 儲存貯體中的金鑰。在範例中,您會先為聯合身分使用者,取得兩個小時的暫時安全登入資料工作階段,並使用它們將經過身分驗證的請求傳送給 Amazon S3。若要執行此範例,您需要建立具有附加政策的 IAM 使用者,以允許使用者要求臨時安全登入資料並列出您的 AWS 資源。以下政策可以完成這個情況:

{ "Statement":[{ "Action":["s3:ListBucket", "sts:GetFederationToken*" ], "Effect":"Allow", "Resource":"*" } ] }

如需如何建立 IAM 使用者的詳細資訊,請參閱《IAM 使用者指南》中的建立第一個 IAM 使用者與管理員群組

在建立 IAM 使用者和附加先前的原則,您可以執行下列的範例。如需建立和測試工作範例的指示,請參閱 AWS SDK for Java 發人員指南中的入門指南。

import com.amazonaws.AmazonServiceException; import com.amazonaws.SdkClientException; import com.amazonaws.auth.AWSStaticCredentialsProvider; import com.amazonaws.auth.BasicSessionCredentials; import com.amazonaws.auth.policy.Policy; import com.amazonaws.auth.policy.Resource; import com.amazonaws.auth.policy.Statement; import com.amazonaws.auth.policy.Statement.Effect; import com.amazonaws.auth.policy.actions.S3Actions; 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.ObjectListing; import com.amazonaws.services.securitytoken.AWSSecurityTokenService; import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClientBuilder; import com.amazonaws.services.securitytoken.model.Credentials; import com.amazonaws.services.securitytoken.model.GetFederationTokenRequest; import com.amazonaws.services.securitytoken.model.GetFederationTokenResult; import java.io.IOException; public class MakingRequestsWithFederatedTempCredentials { public static void main(String[] args) throws IOException { Regions clientRegion = Regions.DEFAULT_REGION; String bucketName = "*** Specify bucket name ***"; String federatedUser = "*** Federated user name ***"; String resourceARN = "arn:aws:s3:::" + bucketName; try { AWSSecurityTokenService stsClient = AWSSecurityTokenServiceClientBuilder .standard() .withCredentials(new ProfileCredentialsProvider()) .withRegion(clientRegion) .build(); GetFederationTokenRequest getFederationTokenRequest = new GetFederationTokenRequest(); getFederationTokenRequest.setDurationSeconds(7200); getFederationTokenRequest.setName(federatedUser); // Define the policy and add it to the request. Policy policy = new Policy(); policy.withStatements(new Statement(Effect.Allow) .withActions(S3Actions.ListObjects) .withResources(new Resource(resourceARN))); getFederationTokenRequest.setPolicy(policy.toJson()); // Get the temporary security credentials. GetFederationTokenResult federationTokenResult = stsClient.getFederationToken(getFederationTokenRequest); Credentials sessionCredentials = federationTokenResult.getCredentials(); // Package the session credentials as a BasicSessionCredentials // object for an Amazon S3 client object to use. BasicSessionCredentials basicSessionCredentials = new BasicSessionCredentials( sessionCredentials.getAccessKeyId(), sessionCredentials.getSecretAccessKey(), sessionCredentials.getSessionToken()); AmazonS3 s3Client = AmazonS3ClientBuilder.standard() .withCredentials(new AWSStaticCredentialsProvider(basicSessionCredentials)) .withRegion(clientRegion) .build(); // To verify that the client works, send a listObjects request using // the temporary security credentials. 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

您可以為同盟使用者和應用程式提供臨時安全登入資料,以便他們傳送經過驗證的要求以存取您的 AWS 資源。請求這些暫時登入資料時,您必須提供使用者名稱,以及說明您想要授予之資源許可的 IAM 原則。預設的工作階段使用期限為一小時。要求聯合身分使用者與應用程式的暫時安全登入資料時,您可以明確地設定不同的持續時間值。如需有關傳送已驗證要求的詳細資訊,請參閱提出要求

注意

當請求用於聯合身分使用者與應用程式的暫時安全登入資料時,為了提高安全,我們建議您使用專用 IAM 使用者,僅進行有必要的存取許可。您所建立暫時使用者的許可絕不可高於已請求暫時安全登入資料的 IAM 使用者。如需詳細資訊,請參閱 AWS Identity and Access Management 常見問答集

您可執行下列項目:

  • 創建 AWS Security Token Service 客戶端,AmazonSecurityTokenServiceClient類的一個實例。

  • 呼叫 STS 用戶端的 GetFederationToken 方法,以啟動工作階段。您需要提供工作階段資訊,包括您要連線至暫時性登入資料的使用者名稱與 IAM 原則。您可以選擇性提供工作階段持續的時間。此方法會傳回暫時安全登入資料。

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

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

下列 C# 範例會列出所指定儲存貯體中的金鑰。在範例中,您會先以聯合身分使用者(User1),取得兩個小時的暫時安全登入資料工作階段,並使用它們將經過身分驗證的請求傳送給 Amazon S3。

  • 在此範例中,請您建立 IAM 使用者,並使其擁有最少許可。若使用 IAM 使用者的登入資料,請您為其他請求暫時性登入資料。此範例僅會列出特定儲存貯體中的此物件。請使用下列附加原則來建立 IAM 使用者:

    { "Statement":[{ "Action":["s3:ListBucket", "sts:GetFederationToken*" ], "Effect":"Allow", "Resource":"*" } ] }

    該政策允許 IAM 使用者請求臨時安全登入資料和存取權限,以列出您的 AWS 資源。如需如何建立 IAM 使用者的詳細資訊,請參閱《IAM 使用者指南》中的建立 IAM 使用者與管理員群組

  • 使用 IAM 使用者安全登入資料來測試下列範例。此範例會使用暫時安全登入資料將經過身分驗證的請求傳送給 Amazon S3。此範例會在要求聯合身分使用者 (使用者 1) 的暫時性安全登入資料時指定下列政策,以限制存取指定儲存貯體 (YourBucketName) 中列出的物件。您必須更新政策,並提供自己的現有儲存貯體名稱。

    { "Statement":[ { "Sid":"1", "Action":["s3:ListBucket"], "Effect":"Allow", "Resource":"arn:aws:s3:::YourBucketName" } ] }
  • 更新下列範例,並提供在上一個聯合身分使用者存取原則中所指定的儲存貯體名稱。如需有關設定和執行程式碼範例的詳細資訊,請參閱 .NET 開發人員指南中的AWS SDK for .NET門。 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 TempFederatedCredentialsTest { 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 client; public static void Main() { ListObjectsAsync().Wait(); } private static async Task ListObjectsAsync() { try { Console.WriteLine("Listing objects stored in a bucket"); // Credentials use the default AWS SDK for .NET credential search chain. // On local development machines, this is your default profile. SessionAWSCredentials tempCredentials = await GetTemporaryFederatedCredentialsAsync(); // Create a client by providing temporary security credentials. using (client = new AmazonS3Client(bucketRegion)) { ListObjectsRequest listObjectRequest = new ListObjectsRequest(); listObjectRequest.BucketName = bucketName; ListObjectsResponse response = await client.ListObjectsAsync(listObjectRequest); List<S3Object> objects = response.S3Objects; Console.WriteLine("Object count = {0}", objects.Count); Console.WriteLine("Press any key to continue..."); Console.ReadKey(); } } catch (AmazonS3Exception e) { Console.WriteLine("Error encountered ***. 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); } } private static async Task<SessionAWSCredentials> GetTemporaryFederatedCredentialsAsync() { AmazonSecurityTokenServiceConfig config = new AmazonSecurityTokenServiceConfig(); AmazonSecurityTokenServiceClient stsClient = new AmazonSecurityTokenServiceClient( config); GetFederationTokenRequest federationTokenRequest = new GetFederationTokenRequest(); federationTokenRequest.DurationSeconds = 7200; federationTokenRequest.Name = "User1"; federationTokenRequest.Policy = @"{ ""Statement"": [ { ""Sid"":""Stmt1311212314284"", ""Action"":[""s3:ListBucket""], ""Effect"":""Allow"", ""Resource"":""arn:aws:s3:::" + bucketName + @""" } ] } "; GetFederationTokenResponse federationTokenResponse = await stsClient.GetFederationTokenAsync(federationTokenRequest); Credentials credentials = federationTokenResponse.Credentials; SessionAWSCredentials sessionCredentials = new SessionAWSCredentials(credentials.AccessKeyId, credentials.SecretAccessKey, credentials.SessionToken); return sessionCredentials; } } }
PHP

本主題說明如何使用第 3 版的類別為聯合身分使用者和應用程式請求臨時安全登入資料,並使用這些登入資源存取 Amazon S3 中存放的資源。 AWS SDK for PHP 有關 Ruby API 的 AWS SDK 的更多信息,請訪問 AWS SDK for Ruby-版本 2

您可以為同盟使用者和應用程式提供臨時安全登入資料,以便他們傳送經過驗證的要求以存取您的 AWS 資源。請求這些暫時登入資料時,您必須提供使用者名稱,以及說明您想要授予之資源許可的 IAM 原則。這些登入資料會在工作階段使用期限到期時到期。工作階段使用期限預設是一小時。在要求用於聯合身分使用者與應用程式的暫時安全登入資料時,您可以明確地為持續時間設定不同的值。如需暫時安全登入資料的詳細資訊,請參閱《IAM 使用者指南》中的暫時安全登入資料。如需有關提供暫時安全登入資料用於聯合身分使用者與應用程式之詳細資料,請參閱 提出要求

在請求用於聯合身分使用者與應用程式得暫時安全登入資料時,為了提高安全,我們建議請使用專用 IAM 使用者,只進行有必要的存取許可。您所建立暫時使用者的許可絕不可高於已請求暫時安全登入資料的 IAM 使用者。如需關於聯合身分的資訊,請參閱 AWS Identity and Access Management 常見問答集

有關 Ruby API 的 AWS SDK 的更多信息,請訪問 AWS SDK for Ruby-版本 2

範例

下列 PHP 範例會列出所指定儲存貯體中的金鑰。在範例中,您會為聯合身分使用者 (User1) 的身分,取得 1 小時的暫時安全登入資料工作階段。然後,請您使用暫時安全登入資料傳送驗證請求給 Amazon S3。

為了提高安全,當請求其他人的暫時登入資料時,使用安全登入資料的 IAM 使用者,有權請求暫時性安全登入資料。為確保 IAM 使用者只授予最有應用程式特定許可給聯合身分使用者,您也可以限制此 IAM 使用者的存取許可。此範例僅會列出特定儲存貯體中的物件。請使用下列附加原則來建立 IAM 使用者:

{ "Statement":[{ "Action":["s3:ListBucket", "sts:GetFederationToken*" ], "Effect":"Allow", "Resource":"*" } ] }

該政策允許 IAM 使用者請求臨時安全登入資料和存取權限,以列出您的 AWS 資源。如需如何建立 IAM 使用者的詳細資訊,請參閱《IAM 使用者指南》中的建立第一個 IAM 使用者與管理員群組

您現在可以使用 IAM 使用者安全登入資料來測試下列範例。此範例會使用暫時安全登入資料將經過身分驗證的請求傳送給 Amazon S3。在要求用於聯合身分使用者 (User1) 的暫時安全登入資料時,此範例指定下列政策,以限制列出特定儲存貯體中物件的存取。使用您儲存貯體名稱更新政策。

{ "Statement":[ { "Sid":"1", "Action":["s3:ListBucket"], "Effect":"Allow", "Resource":"arn:aws:s3:::YourBucketName" } ] }

在下列範例中,您必須在指定政策資源時,將 YourBucketName 取代為您的儲存貯體名稱。

require 'vendor/autoload.php'; use Aws\S3\Exception\S3Exception; use Aws\S3\S3Client; use Aws\Sts\StsClient; $bucket = '*** Your Bucket Name ***'; // In real applications, the following code is part of your trusted code. It has // the security credentials that you use to obtain temporary security credentials. $sts = new StsClient([ 'version' => 'latest', 'region' => 'us-east-1' ]); // Fetch the federated credentials. $sessionToken = $sts->getFederationToken([ 'Name' => 'User1', 'DurationSeconds' => '3600', 'Policy' => json_encode([ 'Statement' => [ 'Sid' => 'randomstatementid' . time(), 'Action' => ['s3:ListBucket'], 'Effect' => 'Allow', 'Resource' => 'arn:aws:s3:::' . $bucket ] ]) ]); // The following will be part of your less trusted code. You provide temporary // security credentials so the code can send authenticated requests to Amazon S3. $s3 = new S3Client([ 'region' => 'us-east-1', 'version' => 'latest', 'credentials' => [ 'key' => $sessionToken['Credentials']['AccessKeyId'], 'secret' => $sessionToken['Credentials']['SecretAccessKey'], 'token' => $sessionToken['Credentials']['SessionToken'] ] ]); try { $result = $s3->listObjects([ 'Bucket' => $bucket ]); } catch (S3Exception $e) { echo $e->getMessage() . PHP_EOL; }
Ruby

您可以為同盟使用者和應用程式提供臨時安全登入資料,以便他們傳送經過驗證的要求以存取您的 AWS 資源。向 IAM 服務請求這些暫時登入資料時,您必須提供使用者名稱,以及說明您想要授予之資源許可的 IAM 原則。工作階段使用期限預設是一小時。不過,如果您要使用 IAM 使用者登入資料來請求暫時登入資料,則可以在請求聯合身分使用者與應用程式的暫時安全登入資料時明確地設定不同的持續時間值。如需更多有關聯合身分使用者的暫時安全登入資料與應用程式,請參閱 提出要求

注意

為了提高安全,請求聯合身分使用者與應用程式的暫時安全登入資料,您可能會想要使用只具有必要存取許可的專用 IAM 使用者。您所建立暫時使用者的許可絕不可高於已請求暫時安全登入資料的 IAM 使用者。如需詳細資訊,請參閱 AWS Identity and Access Management 常見問答集

範例

下列 Ruby 程式碼範例允許聯合身分使用者具有有限許可,以設定在指定儲存貯體中的金鑰清單。

# Prerequisites: # - An existing Amazon S3 bucket. require "aws-sdk-s3" require "aws-sdk-iam" require "json" # Checks to see whether a user exists in IAM; otherwise, # creates the user. # # @param iam [Aws::IAM::Client] An initialized IAM client. # @param user_name [String] The user's name. # @return [Aws::IAM::Types::User] The existing or new user. # @example # iam = Aws::IAM::Client.new(region: 'us-west-2') # user = get_user(iam, 'my-user') # exit 1 unless user.user_name # puts "User's name: #{user.user_name}" def get_user(iam, user_name) puts "Checking for a user with the name '#{user_name}'..." response = iam.get_user(user_name: user_name) puts "A user with the name '#{user_name}' already exists." return response.user # If the user doesn't exist, create them. rescue Aws::IAM::Errors::NoSuchEntity puts "A user with the name '#{user_name}' doesn't exist. Creating this user..." response = iam.create_user(user_name: user_name) iam.wait_until(:user_exists, user_name: user_name) puts "Created user with the name '#{user_name}'." return response.user rescue StandardError => e puts "Error while accessing or creating the user named '#{user_name}': #{e.message}" end # Gets temporary AWS credentials for an IAM user with the specified permissions. # # @param sts [Aws::STS::Client] An initialized AWS STS client. # @param duration_seconds [Integer] The number of seconds for valid credentials. # @param user_name [String] The user's name. # @param policy [Hash] The access policy. # @return [Aws::STS::Types::Credentials] AWS credentials for API authentication. # @example # sts = Aws::STS::Client.new(region: 'us-west-2') # credentials = get_temporary_credentials(sts, duration_seconds, user_name, # { # 'Version' => '2012-10-17', # 'Statement' => [ # 'Sid' => 'Stmt1', # 'Effect' => 'Allow', # 'Action' => 's3:ListBucket', # 'Resource' => 'arn:aws:s3:::doc-example-bucket' # ] # } # ) # exit 1 unless credentials.access_key_id # puts "Access key ID: #{credentials.access_key_id}" def get_temporary_credentials(sts, duration_seconds, user_name, policy) response = sts.get_federation_token( duration_seconds: duration_seconds, name: user_name, policy: policy.to_json ) return response.credentials rescue StandardError => e puts "Error while getting federation token: #{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, 'doc-example-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 return true rescue StandardError => e puts "Error while accessing the bucket named '#{bucket_name}': #{e.message}" end # Example usage: def run_me region = "us-west-2" user_name = "my-user" bucket_name = "doc-example-bucket" iam = Aws::IAM::Client.new(region: region) user = get_user(iam, user_name) exit 1 unless user.user_name puts "User's name: #{user.user_name}" sts = Aws::STS::Client.new(region: region) credentials = get_temporary_credentials(sts, 3600, user_name, { "Version" => "2012-10-17", "Statement" => [ "Sid" => "Stmt1", "Effect" => "Allow", "Action" => "s3:ListBucket", "Resource" => "arn:aws:s3:::#{bucket_name}" ] } ) exit 1 unless credentials.access_key_id puts "Access key ID: #{credentials.access_key_id}" s3_client = Aws::S3::Client.new(region: region, credentials: credentials) exit 1 unless list_objects_in_bucket?(s3_client, bucket_name) end run_me if $PROGRAM_NAME == __FILE__

相關資源