AWS SDK for Javaを使う#AWS Identity and Access Management(IAM)

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

いまやクラウドサービスの代表格とも言えるAmazonですが、EC2やS3をはじめとして、さまざまなサービスを提供しています。
数年前に私も少しだけEC2やS3を使用したことがあるのですが、最近はあまりさわっていませんでした。
しかし今回AWSについての調査をきっかけに、各種AWSサービスについて復習&AWS SDKでの動作確認をしていきたいと思います。

今回はAWSのアカウント管理機能、Amazon IAMです。

今回使用した動作環境は以下のとおりです。

  • OS : MacOS X 10.7.2
  • Java : 1.6.0_26
  • Scala : 2.9.1 final
  • SBT : 0.11.2

なお、AWSへの登録は終わっているものとします。

Amazon IAM

Amazon Identity and Access Management(IAM)とは、AWSサービスへのアクセスをコントロールするための仕組みです。
いままでAWS登録時のアカウントを使用してEC2のインスタンス立ち上げやDBへの保存をおこなってきました。
これはUnixでいえばrootですべて操作しているようなもので、非常に危険です。
しかしIAMを使用すれば、アカウントを新しく作成し、各種AWSのサービスへのアクセスを細かく制御できます。
今回はIAM用APIを使用してアクセス制御をおこなってみましょう。
※IAMの使用方法自体はAWS Identity and Access Managementで管理されるグループとユーザを御覧ください

実行環境のセットアップ

以前と同じくsbt + scala + aws-sdk-javaをセットアップしておきましょう。

Amazon IAMサンプル作成

サンプルの作成です。今回はIAMアカウントを作成し、そのアカウントでS3に対してアクセスしてみます。
IAMアカウントはS3のREAD系アクションのみ許可し、それ以外のサービスについては許可しません。
順番にみていきましょう。

まずはいつものキーでIAMクライアントを作成します。その後myGroupという名前のグループを作成し、そのグループに対してポリシーを適用しています。
ポリシーはJSON形式で記述し、許可するサービスなどを定義します。ここではS3のREAD系のみを許可しています。

  //アクセスキー
  val accessKey = "アクセスキー"
  //シークレットキー
  val secretKey = "シークレットキー"
  val credentials = new BasicAWSCredentials(accessKey,secretKey)
  //ポリシー定義
  val doc = """{"Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetBucketAcl",
         ・
         ・
         ・
        "s3:ListBucketVersions",
        "s3:ListMultipartUploadParts"
      ],
      "Resource": [
        "*"
      ]
    }
  ]
}"""

  //IAMオブジェクト作成
  val iam = new AmazonIdentityManagementClient(credentials)

  //グループ作成
  val group = new CreateGroupRequest("myGroup")
  val resGroup = iam.createGroup(group)
  println("groupId = " + resGroup.getGroup().getGroupId)

  //グループポリシー作成
  val policy = new PutGroupPolicyRequest("myGroup","myPolicy",doc)
  iam.putGroupPolicy(policy)

グループにポリシーを付与した後は、IAMユーザーを作成します。(createUser)
作成したユーザーはさっきつくったグループに加えてあげましょう。

  
  //IAMユーザー作成
  val createUserRequest = new CreateUserRequest().withUserName("myTestUser")
  val user = iam.createUser(createUserRequest)
  println(user.getUser())

  Thread.sleep(3000)

  // ユーザーをグループに追加
  val addUserToGroupRequest = new AddUserToGroupRequest().withGroupName("myGroup").withUserName("myTestUser");
  iam.addUserToGroup(addUserToGroupRequest);

これでIAMユーザーはS3へのREADのみ許可された状態になったので、createAccessKeyメソッドでキーを取得しましょう。
CreateAccessKeyResultオブジェクト経由で、アクセスキーとシークレットキーを取得できます。

  // アクセスキー作成
  val createAccessKeyRequest = new CreateAccessKeyRequest().withUserName("myTestUser")
  val createAccessKeyResult = iam.createAccessKey(createAccessKeyRequest)
 
  Thread.sleep(3000)

  val aKey = createAccessKeyResult.getAccessKey().getAccessKeyId()
  val sKey = createAccessKeyResult.getAccessKey().getSecretAccessKey() 

  Thread.sleep(3000)

IAMユーザーでBasicAWSCredentialsを作成し、S3にアクセスしています。
listObjectsは成功しますが、createBucketはエラーになります。

  //許可されている操作をおこなってみる  
  val userCredentials = new BasicAWSCredentials(aKey,sKey)
  val s3 = new AmazonS3Client(userCredentials)
  val objectListing = s3.listObjects(new ListObjectsRequest().withBucketName("somebucket"))
  for (objectSummary <- objectListing.getObjectSummaries()) {
    println(" - " + objectSummary.getKey() + "  " + "(size = " + objectSummary.getSize() + ")")
  }

  //許可されていない動作をおこなってみる
  try {
	s3.createBucket("cannot-create-bucket")
	throw new Exception("The operation should not succeed")
  } catch {
	case e:Exception => println("---exception ok---")
  }
}

サンプルプログラムの全文です。実行後はAWS Management Consoleでユーザーやグループを削除しておいてください。

import com.amazonaws._
import com.amazonaws.auth._
import com.amazonaws.services.s3.AmazonS3
import com.amazonaws.services.s3.AmazonS3Client
import com.amazonaws.services.s3.model._
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClient
import com.amazonaws.services.identitymanagement.model._

import scala.collection.JavaConversions._

object IAMMain extends App {

  //アクセスキー
  val accessKey = "アクセスキー"
  //シークレットキー
  val secretKey = "シークレットキー"

  val credentials = new BasicAWSCredentials(accessKey,secretKey)

  //ポリシー定義
  val doc = """{"Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetBucketAcl",
        "s3:GetBucketLocation",
        "s3:GetBucketNotification",
        "s3:GetBucketPolicy",
        "s3:GetBucketRequestPayment",
        "s3:GetBucketVersioning",
        "s3:GetObject",
        "s3:GetObjectAcl",
        "s3:GetObjectVersion",
        "s3:GetObjectVersionAcl",
        "s3:ListAllMyBuckets",
        "s3:ListBucket",
        "s3:ListBucketMultipartUploads",
        "s3:ListBucketVersions",
        "s3:ListMultipartUploadParts"
      ],
      "Resource": [
        "*"
      ]
    }
  ]
}"""

  //IAMオブジェクト作成
  val iam = new AmazonIdentityManagementClient(credentials)

  //グループ作成
  val group = new CreateGroupRequest("myGroup")
  val resGroup = iam.createGroup(group)
  println("groupId = " + resGroup.getGroup().getGroupId)

  //グループポリシー作成
  val policy = new PutGroupPolicyRequest("myGroup","myPolicy",doc)
  iam.putGroupPolicy(policy)

  Thread.sleep(3000)

  //IAMユーザー作成
  val createUserRequest = new CreateUserRequest().withUserName("myTestUser")
  val user = iam.createUser(createUserRequest)
  println(user.getUser())

  Thread.sleep(3000)

  // ユーザーをグループに追加
  val addUserToGroupRequest = new AddUserToGroupRequest().withGroupName("myGroup").withUserName("myTestUser");
  iam.addUserToGroup(addUserToGroupRequest);

  Thread.sleep(3000)

  // アクセスキー作成
  val createAccessKeyRequest = new CreateAccessKeyRequest().withUserName("myTestUser")
  val createAccessKeyResult = iam.createAccessKey(createAccessKeyRequest)
 
  Thread.sleep(3000)

  val aKey = createAccessKeyResult.getAccessKey().getAccessKeyId()
  val sKey = createAccessKeyResult.getAccessKey().getSecretAccessKey() 

  Thread.sleep(3000)


  //許可されている操作をおこなってみる  
  val userCredentials = new BasicAWSCredentials(aKey,sKey)
  val s3 = new AmazonS3Client(userCredentials)
  val objectListing = s3.listObjects(new ListObjectsRequest().withBucketName("somebucket"))
  for (objectSummary <- objectListing.getObjectSummaries()) {
    println(" - " + objectSummary.getKey() + "  " + "(size = " + objectSummary.getSize() + ")")
  }

  //許可されていない動作をおこなってみる
  try {
	s3.createBucket("cannot-create-bucket")
	throw new Exception("The operation should not succeed")
  } catch {
	case e:Exception => println("---exception ok---")
  }
}

まとめ

今回はIAMのAPIを使用してみました。S3アクセス専用ユーザーなど、権限を細かくコントロールしたいケースは多いので、よく使うと思います。

参考サイトなど