

 適用於 Java 的 AWS SDK 1.x 已於 2025 年 12 月 31 日end-of-support。我們建議您遷移至 [AWS SDK for Java 2.x](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/home.html)，以繼續接收新功能、可用性改善和安全性更新。

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

# 使用 IAM 角色授予 上 AWS 資源的存取權 Amazon EC2
<a name="java-dg-roles"></a>

所有對 Amazon Web Services (AWS) 的請求都必須使用 發出的登入資料進行密碼編譯簽署 AWS。您可以使用 *IAM 角色*，方便地從 Amazon EC2 執行個體授予 AWS 資源的安全存取權。

本主題提供如何搭配執行 的 Java SDK 應用程式使用 IAM 角色的相關資訊 Amazon EC2。如需 IAM 執行個體的詳細資訊，請參閱《Linux 執行個體 Amazon EC2 使用者指南》中的適用於 的 [IAM 角色 Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html)。

## 預設提供者鏈和 EC2 執行個體描述檔
<a name="default-provider-chain"></a>

如果您的應用程式使用預設建構函數建立 AWS 用戶端，則用戶端將依下列順序使用*預設憑證提供者鏈結搜尋憑證*：

1. 在 Java 系統屬性中：`aws.accessKeyId` 和 `aws.secretKey`。

1. 在系統環境變數中：`AWS_ACCESS_KEY_ID` 和 `AWS_SECRET_ACCESS_KEY`。

1. 在預設登入資料檔案中 (此檔案的位置因平台而異)。

1. 如果已設定`AWS_CONTAINER_CREDENTIALS_RELATIVE_URI`環境變數，且安全管理員具有存取變數的許可，則透過 Amazon EC2 容器服務傳遞的登入資料。

1. 在*執行個體描述檔登入資料*中，這存在於與 EC2 執行個體的 IAM 角色關聯的執行個體中繼資料內。

1. 來自環境或容器的 Web Identity Token 登入資料。

預設供應商鏈中的*執行個體描述檔登入*資料步驟只有在 Amazon EC2 執行個體上執行應用程式時才能使用，但在使用 Amazon EC2 執行個體時提供最大的使用便利性和最佳安全性。您也可以直接傳遞 [InstanceProfileCredentialsProvider](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/auth/InstanceProfileCredentialsProvider.html) 執行個體給用戶端建構函數來取得執行個體描述檔登入資料，而無須繼續進行整個預設供應者鏈結。

例如：

```
AmazonS3 s3 = AmazonS3ClientBuilder.standard()
              .withCredentials(new InstanceProfileCredentialsProvider(false))
              .build();
```

使用此方法時，開發套件會擷取暫時 AWS 登入資料，其許可與執行個體描述檔中與 Amazon EC2 執行個體相關聯之 IAM 角色的許可相同。雖然這些登入資料是暫時的，最終會過期， `InstanceProfileCredentialsProvider`會定期為您重新整理，以便取得的登入資料繼續允許存取 AWS。

**重要**  
自動登入資料重新整理*只會*在您使用預設用戶端建構函數時發生，這會建立自己的 `InstanceProfileCredentialsProvider` 做為預設提供者鏈結的一部分，或當您將`InstanceProfileCredentialsProvider`執行個體直接傳遞給用戶端建構函數時。如果您使用其他方法來取得或傳遞執行個體描述檔登入資料，則需負責檢查和重新整理過期的登入資料。

如果用戶端建構函式無法使用登入資料提供者鏈結找到登入資料，則會擲回 [AmazonClientException](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/AmazonClientException.html)。

## 逐步解說：針對 EC2 執行個體使用 IAM 角色
<a name="roles-walkthrough"></a>

下列逐步解說說明如何 Amazon S3 使用 IAM 角色從 擷取物件來管理存取。

### 建立 IAM 角色
<a name="java-dg-create-the-role"></a>

建立授予唯讀存取權的 IAM 角色 Amazon S3。

1. 開啟 [IAM 主控台](https://console.aws.amazon.com/iam/home)。

1. 在導覽窗格中，選取**角色**，然後選取**建立新角色**。

1. 輸入角色的名稱，然後選擇 **Next Step (下一步)**。請記住此名稱，因為當您啟動 Amazon EC2 執行個體時，您將需要此名稱。

1. 在**選取角色類型**頁面** AWS 服務 的角色**下，選取 ** Amazon EC2 **。

1. 在**設定許可**頁面的**選取政策範本**下，選取** Amazon S3 唯讀存取**，然後選取**下一步**。

1. 在**檢閱**頁面上，選取**建立角色**。

### 啟動 EC2 執行個體時並指定 IAM 角色
<a name="java-dg-launch-ec2-instance-with-instance-profile"></a>

您可以使用 Amazon EC2 主控台或 啟動具有 IAM 角色的 Amazon EC2 執行個體 適用於 Java 的 AWS SDK。
+ 若要使用主控台啟動 Amazon EC2 執行個體，請遵循 [Amazon EC2 Linux 執行個體使用者指南中 Linux 執行個體入門](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EC2_GetStarted.html)的指示。 Amazon EC2 

  當您到達 **Review Instance Launch (檢閱執行個體啟動)** 頁面時，選取 **Edit instance details (編輯執行個體詳細資訊)**。在 **IAM 角色**中，選擇您先前建立的 IAM 角色。依照指示完成程序。
**注意**  
您需要建立或使用現有的安全群組與金鑰對，以連接到執行個體。
+ 若要使用 啟動具有 IAM 角色的 Amazon EC2 執行個體 適用於 Java 的 AWS SDK，請參閱[執行 Amazon EC2 執行個體](run-instance.md)。

### 建立您的應用程式
<a name="java-dg-remove-the-credentials"></a>

讓我們建置要在 EC2 執行個體上執行的範例應用程式。首先，建立可用來保存教學課程檔案的目錄 （例如 `GetS3ObjectApp`)。

接著，將 適用於 Java 的 AWS SDK 程式庫複製到新建立的目錄。如果您將 下載 適用於 Java 的 AWS SDK 到您的`~/Downloads`目錄，您可以使用下列命令來複製它們：

```
cp -r ~/Downloads/aws-java-sdk-{1.7.5}/lib .
cp -r ~/Downloads/aws-java-sdk-{1.7.5}/third-party .
```

開啟新檔案、呼叫 `GetS3Object.java`，然後新增下列程式碼：

```
import java.io.*;

import com.amazonaws.auth.*;
import com.amazonaws.services.s3.*;
import com.amazonaws.services.s3.model.*;
import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;

public class GetS3Object {
  private static final String bucketName = "text-content";
  private static final String key = "text-object.txt";

  public static void main(String[] args) throws IOException
  {
    AmazonS3 s3Client = AmazonS3ClientBuilder.defaultClient();

    try {
      System.out.println("Downloading an object");
      S3Object s3object = s3Client.getObject(
          new GetObjectRequest(bucketName, key));
      displayTextInputStream(s3object.getObjectContent());
    }
    catch(AmazonServiceException ase) {
      System.err.println("Exception was thrown by the service");
    }
    catch(AmazonClientException ace) {
      System.err.println("Exception was thrown by the client");
    }
  }

  private static void displayTextInputStream(InputStream input) throws IOException
  {
    // Read one text line at a time and display.
    BufferedReader reader = new BufferedReader(new InputStreamReader(input));
    while(true)
    {
      String line = reader.readLine();
      if(line == null) break;
      System.out.println( "    " + line );
    }
    System.out.println();
  }
}
```

開啟新檔案、呼叫 `build.xml`，然後新增下列行：

```
<project name="Get {S3} Object" default="run" basedir=".">
  <path id="aws.java.sdk.classpath">
    <fileset dir="./lib" includes="**/*.jar"/>
    <fileset dir="./third-party" includes="**/*.jar"/>
    <pathelement location="lib"/>
    <pathelement location="."/>
  </path>

  <target name="build">
  <javac debug="true"
    includeantruntime="false"
    srcdir="."
    destdir="."
    classpathref="aws.java.sdk.classpath"/>
  </target>

  <target name="run" depends="build">
    <java classname="GetS3Object" classpathref="aws.java.sdk.classpath" fork="true"/>
  </target>
</project>
```

建置並執行修改過的程式。請注意，程式中不會儲存任何登入資料。因此，除非您已指定 AWS 登入資料，否則程式碼會擲回 `AmazonServiceException`。例如：

```
$ ant
Buildfile: /path/to/my/GetS3ObjectApp/build.xml

build:
  [javac] Compiling 1 source file to /path/to/my/GetS3ObjectApp

run:
   [java] Downloading an object
   [java] AmazonServiceException

BUILD SUCCESSFUL
```

### 將編譯的程式傳輸至您的 EC2 執行個體
<a name="java-dg-transfer-compiled-program-to-ec2-instance"></a>

使用安全複本 ()** `` **以及 適用於 Java 的 AWS SDK 程式庫，將程式傳輸至您的 Amazon EC2 執行個體。命令的序列如下所示。

```
scp -p -i {my-key-pair}.pem GetS3Object.class ec2-user@{public_dns}:GetS3Object.class
scp -p -i {my-key-pair}.pem build.xml ec2-user@{public_dns}:build.xml
scp -r -p -i {my-key-pair}.pem lib ec2-user@{public_dns}:lib
scp -r -p -i {my-key-pair}.pem third-party ec2-user@{public_dns}:third-party
```

**注意**  
根據您使用的 Linux 發行版本，*使用者名稱*可能是 "ec2-user"、"root" 或 "ubuntu"。若要取得執行個體的公有 DNS 名稱，請開啟 [EC2 主控台](https://console.aws.amazon.com/ec2/home)，並在**描述**索引標籤中尋找**公有 DNS** 值 （例如，`ec2-198-51-100-1.compute-1.amazonaws.com`)。

在上述命令中：
+  `GetS3Object.class` 是您編譯的程式
+  `build.xml` 是用來建置和執行程式的 ant 檔案
+ `lib` 和 `third-party`目錄是來自 的對應程式庫資料夾 適用於 Java 的 AWS SDK。
+ `-r` 切換表示 `scp`應該對 適用於 Java 的 AWS SDK 分佈中 `library`和 `third-party`目錄的所有內容進行遞迴複製。
+ `-p` 切換會指出 `scp`應在來源檔案複製到目的地時保留其許可。
**注意**  
`-p` 交換器僅適用於 Linux、macOS 或 Unix。如果您要從 Windows 複製檔案，您可能需要使用以下命令修正執行個體上的檔案許可：

```
chmod -R u+rwx GetS3Object.class build.xml lib third-party
```

### 在 EC2 執行個體上執行範例程式
<a name="java-dg-run-the-program"></a>

若要執行程式，請連線至您的 Amazon EC2 執行個體。如需詳細資訊，請參閱《[Linux 執行個體使用者指南》中的連線至您的](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AccessingInstances.html) Linux 執行個體。 Amazon EC2 

如果您的執行個體**` ant `**無法使用 ，請使用下列命令安裝它：

```
sudo yum install ant
```

然後，使用 執行程式`ant`，如下所示：

```
ant run
```

程式會將 Amazon S3 物件的內容寫入命令視窗。