使用 IAM 角色授予对 Amazon EC2 上的 Amazon 资源的访问权 - Amazon SDK for Java 1.x
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

我们宣布了即将推出 end-of-support 的 Amazon SDK for Java (v1)。建议您迁移到 Amazon SDK for Java v2。有关日期、其他详细信息以及如何迁移的信息,请参阅链接的公告。

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用 IAM 角色授予对 Amazon EC2 上的 Amazon 资源的访问权

必须通过使用由 Amazon 颁发的凭证对发送到 Amazon Web Services (Amazon) 的所有请求进行加密签名。可以使用 IAM 角色 方便地授予对 Amazon EC2 实例上的 Amazon 资源的安全访问权。

本主题介绍如何将 IAM 角色与 Amazon EC2 上运行的 Java SDK 应用程序结合使用。有关 IAM 实例的更多信息,请参阅《Amazon EC2 用户指南(适用于 Linux 实例)》中的适用于 Amazon EC2 的 IAM 角色

默认提供程序链和 EC2 实例配置文件

如果您的应用程序使用默认构造函数创建 Amazon 客户端,则该客户端将按照以下顺序使用默认凭证提供程序链 搜索凭证:

  1. Java 系统属性:aws.accessKeyIdaws.secretKey

  2. 系统环境变量:AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY

  3. 默认凭证文件 (在不同平台上该文件位于不同位置)。

  4. 如果已设置 AWS_CONTAINER_CREDENTIALS_RELATIVE_URI 环境变量且安全管理器有权访问该变量,则为通过 Amazon EC2 容器服务传递的凭证。

  5. 实例配置文件凭证,包含在与 EC2 实例的 IAM 角色关联的实例元数据中。

  6. 来自环境或容器的 Web 身份令牌凭证。

只有在对 Amazon EC2 实例运行应用程序时,默认提供程序链中的实例配置文件凭证 步骤才可用,但在处理 Amazon EC2 实例时,该步骤能够最大限度地简化使用过程并提高安全性。您还可以将 InstanceProfileCredentialsProvider 实例直接传递给客户端构造函数,这样无需执行整个默认提供程序链即可获取实例配置文件凭证。

例如:

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

在使用该方法时,SDK 在其实例配置文件中,检索与 Amazon EC2 实例的关联 IAM 角色的关联凭证具有相同权限的临时 Amazon 凭证。尽管这些凭证是临时凭证,而且最终会过期,但 InstanceProfileCredentialsProvider 会定期为您刷新它们,保证您收到的凭证可继续访问 Amazon。

重要

在以下情况下执行自动凭证刷新:您使用默认客户端构造函数 (它会创建其自身的 InstanceProfileCredentialsProvider 作为默认提供程序链的内容) 时;或者您将 InstanceProfileCredentialsProvider 实例直接传递给客户端构造函数时。如果您使用其他方法获取或传送实例配置文件凭证,您将负责检查和刷新过期凭证。

如果客户端构造函数使用凭证提供程序链找不到凭证,它会引发 AmazonClientException

演练:将 IAM 角色用于 EC2 实例

以下演练将介绍如何使用 IAM 角色从 Amazon S3 中检索对象以管理访问。

创建 IAM 角色

创建授予对 Amazon S3 的只读访问权的 IAM 角色。

  1. 打开 IAM 控制台

  2. 在导航窗格中,选择 RolesCreate New Role

  3. 输入角色名称,然后选择 Next Step。请记住此名称,因为在启动 Amazon EC2 实例时会用到它。

  4. 选择角色类型页面的 Amazon Web Service 角色下,选择 Amazon EC2

  5. 设置权限页面的选择策略模板下,选择 Amazon S3 只读访问权限,然后选择下一步

  6. Review 页面上,选择 Create Role

启动 EC2 实例并指定您的 IAM 角色

您可通过 Amazon EC2 控制台或 Amazon SDK for Java,使用 IAM 角色启动 Amazon EC2 实例。

  • 要使用控制台启动 Amazon EC2 实例,请按照《Amazon EC2 用户指南(适用于 Linux 实例)》Amazon EC2 Linux 实例入门中的说明操作。

    到达核查实例启动页面时,选择编辑实例详细信息。在 IAM 角色中,选择您之前创建的 IAM 角色。按指示完成该过程。

    注意

    您需要创建或使用现有安全组和密钥对,才能连接到该实例。

  • 要使用Amazon SDK for Java 通过 IAM 角色启动 Amazon EC2 实例,请参阅运行 Amazon EC2 实例

创建您的应用程序

让我们来构建在 EC2 实例上运行的示例应用程序。首先,创建一个目录来用于保存教程文件 (例如,GetS3ObjectApp)。

然后,将 Amazon SDK for Java 库复制到新创建的目录中。如果已将Amazon SDK for Java下载到 ~/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>

构建并运行修改后的程序。请注意,该程序中未存储凭证。所以,除非您已经指定 Amazon 凭证,否则代码会引发 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 实例

使用安全复制 (Amazon EC2 ),将程序连同 库传输到 Amazon SDK for Java 实例。该命令序列与以下序列相似。

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 控制台并在描述选项卡中查找公有 DNS 值(例如 ec2-198-51-100-1.compute-1.amazonaws.com)。

在上述命令中:

  • GetS3Object.class 是已编译的程序

  • build.xml 是用于构建和运行您的程序的 Ant 文件

  • libthird-party 目录是Amazon SDK for Java中对应的库文件夹。

  • -r 开关指示 scp 应该对Amazon SDK for Java版本的 librarythird-party 目录中的所有内容以递归方式进行复制。

  • -p 开关指示 scp 在将源文件复制到目标位置时,应保留对应文件的权限。

    注意

    -p 开关仅适用于 Linux、macOS 或 Unix。如果您从 Windows 中复制文件,可能需要使用以下命令在实例上修复文件权限:

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

在 EC2 实例上运行示例程序

要运行程序,请连接到 Amazon EC2 实例。有关更多信息,请参阅《Amazon EC2 用户指南(适用于 Linux 实例)》中的连接到您的 Linux 实例

如果 ant 在您的实例上不可用,请使用以下命令安装它:

sudo yum install ant

然后使用 ant 运行程序,如下所示:

ant run

该程序会将 Amazon S3 对象的内容写入命令窗口。