使用 IAM 角色授予对 Amazon EC2 上的 AWS 资源的访问权 - 适用于 Java 的 AWS 开发工具包
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

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

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

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

本主题介绍如何使用 IAM 角色操作 Amazon EC2 上运行的 Java 开发工具包应用程序。有关 IAM 实例的更多信息,请参阅 Amazon EC2 User Guide for Linux Instances中的Amazon EC2 的 IAM 角色

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

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

  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 实例运行应用程序时,默认提供程序链中的 instance profile credentials (实例配置文件证书) 步骤才可用,但在处理 Amazon EC2 实例时,该步骤能够最大限度地简化使用过程并提高安全性。您还可以将 InstanceProfileCredentialsProvider 实例直接传递给客户端构造函数,以便获取实例配置文件凭证,而无需执行整个默认提供程序链。

例如:

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

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

重要

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

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

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

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

创建 IAM 角色

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

创建 IAM 角色

  1. 打开 IAM 控制台

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

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

  4. Select Role Type 页面上,在 AWS Service Roles 下选择 Amazon EC2

  5. Set Permissions 页面上,在 Select Policy Template 下选择 Amazon S3 Read Only Access,然后选择 Next Step

  6. Review 页面上,选择 Create Role

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

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

  • 要使用控制台启动 Amazon EC2 实例,请参阅 Amazon EC2 User Guide for Linux Instances中的 Amazon EC2 Linux 实例入门

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

    注意

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

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

创建您的应用程序

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

然后,将 AWS SDK for Java 库复制到新创建的目录中。如果已将AWS 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 String bucketName = "text-content"; private static 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 Amazon 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 实例

使用安全复制 (scp),将程序连同AWS SDK for Java库传输到 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 控制台,然后在 Description (描述) 选项卡中查找 Public DNS (公有 DNS) 值(例如,ec2-198-51-100-1.compute-1.amazonaws.com)。

在上述命令中:

  • GetS3Object.class 是已编译的程序

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

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

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

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

    注意

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

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

在 EC2 实例上运行示例程序

要运行程序,请连接到 Amazon EC2 实例。有关更多信息,请参阅 Amazon EC2 User Guide for Linux Instances 中的连接到您的 Linux 实例

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

sudo yum install ant

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

ant run

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