AWS IAMのIdentity Federationを使うIdentity Broker(C#編)

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

本記事は下記Java版のIdentity Broker記事のC#版です。

・Identity Federationを使うIdentity BrokerをJavaで書いてみた
https://dev.classmethod.jp/cloud/identity-federation-identity-broker-java/

IAMのID統合(Identity Federation)機能(復習)

AWSのIAMにはID統合機能が用意されています。これは特定のID管理サービス(LDAP、Active Directory、Webアプリケーションのユーザー管理機能等)で管理されるユーザーとIAMユーザーを関連付けることにより、ユーザー個別の一時証明書を発行し、それを利用してAmazon S3やAmazon DynamoDBなどのAWSリソースにアクセスできるようにする機能です。

ID統合のイメージは下記のようになります:

id_federation_csharp_01

AWSとAndroid、AWSとiOSを連携する際のIdentity Federationに関する記事は下記をご参照下さい。

・クラウド「AWS」とAndroidを直結するSDKで何ができるのか?(1/3) - @IT
http://www.atmarkit.co.jp/fsmart/articles/smaphocloud02/01.html

・クラウドストレージ「Amazon S3」とiPhone/iPadを直結するSDKとは(1/3) - @IT
http://www.atmarkit.co.jp/fsmart/articles/smaphocloud03/01.html

・@ITスマホ×クラウド連載 第2回 AWS×Android:補足記事(2)Token Vending MachineとSecurity Token Service
https://dev.classmethod.jp/cloud/atmarkit_smartphone_cloud_02_supplement_02/

Identity BrokerをC#で書いてみる

今回はC#でIdentity Brokerを書いてみたいと思います。本記事で作成する範囲は下記になります。

id_federation_csharp_02

 (Amazon S3へのC#によるファイルアップロードに関しては続きとなるこちらの記事をご確認下さい)

Visual StudioにAWS Toolkit for Microsoft Visual Studioがインストールされている方はAWS Console Projectを作成して下さい。そうでない方は、まず下記の記事を参考に環境構築を行なって下さい。

・AWS Toolkit for Microsoft Visual Studioをインストールしてみる
https://dev.classmethod.jp/cloud/aws-toolkit-for-visual-studio/

 アプリケーションとしては図で奥の方にあるコンポーネント(ADServiceMock.cs)から作成していきます。

ADMockService.cs

 Accountエンティティを作成します。

class Account
{
    public String Id { get; set; }
    public String Name { get; set; }
    public String Email { get; set; }
}

次にAccountを管理するADMockServiceを作成します。user1という名前ならばAccountインスタンスを返します。違うならばnullを返します。

class ADServiceMock
{
    public Account login(String name, String pass)
    {
        Account returnValue = null;

        if ("user1".Equals(name))
        {
            Account account = new Account();
            account.Id = "00001";
            account.Name = name;
            account.Email = "a@b.com";

            returnValue = account;
        }

        return returnValue;
    }
}

IdentityBroker.cs

 次にIdentityBrokerを作成します。具体的には以下の処理を行います。

  • ユーザー名とパスワードが渡される
  • ADMockServiceに問い合わせを行う
  • OKであれば指定したポリシーの一時証明書AWS Security Token Serviceから取得する
  • 一時証明書を返す

class IdentityBroker
{
    private const int DURATION = 3600;

    public static Credentials getToken(String name, String pass)
    {
        // check account
        var activeDirectory = new ADServiceMock();
        var account = activeDirectory.login(name, pass);

        if (account == null)
        {
            return null;
        }

        var stsClient = new AmazonSecurityTokenServiceClient();
        String policy = File.ReadAllText("Policy.txt");

        GetFederationTokenRequest request = new GetFederationTokenRequest();
        request.WithDurationSeconds(DURATION).WithPolicy(policy).WithName(name);

        var result = stsClient.GetFederationToken(request);
        var credentials = result.GetFederationTokenResult.Credentials;

        return credentials;
    }
}

ここで利用しているポリシーファイルは下記のようになります。

{
    "Statement":[
        {
            "Effect":"Allow",
            "Action": [
                "s3:ListBucket",
                "s3:PutObject*"
            ],
            "Resource":"arn:aws:s3:::mybucketname"
        },
        {
            "Effect":"Allow",
            "Action": [
                "s3:GetObject*"
            ],
            "Resource":"arn:aws:s3:::mybucketname/*"
        }
    ]
}

ポリシーファイルではS3でのバケット一覧の取得とオブジェクトのPUT、及びオブジェクトのGETを許可しています。

Program.cs

今回のサンプルのビジネスアプリケーションに相当する部分です。ユーザー名とパスワードがプログラムに渡されると、一時証明書が返されます。今回は一時証明書の取得までを行い、実際にその一時証明書の中身を確認してみたいと思います。

public static void Main(string[] args) { Console.Write(GetServiceOutput(args)); Console.Read(); }

public static string GetServiceOutput(string[] args) { StringBuilder sb = new StringBuilder(1024); using (StringWriter sr = new StringWriter(sb)) { if (args.Length < 2) { sr.WriteLine("Usage: IdentityBrokerSample name password"); return sb.ToString(); } var credentials = IdentityBroker.getToken(args[0], args[1]); if (credentials == null) { sr.WriteLine("Authentication Failure."); return sb.ToString(); } } } [/csharp]

 それではアプリケーションを実行しましょう。デバッグの開始オプションでuser1 passwordを指定すると正しく動作します。

var credentialsが定義されている行にブレークポイント置いてCredentialsオブジェクトの中身をみてみると下記のようになります:

id_federation_csharp_03

お馴染みのアクセスキー(AccessKeyId)、シークレットアクセスキー(SecretAccessKey)が取得できていることがわかります。また、これらとは別にSessionTokenが取得されており、また、Expirationが設定されています。ここではExpiration = "2013/02/15 17:24:20"となっています。16時24分にアプリケーションを実行したので、一時証明書はデフォルトでは1時間有効であることがわかります。SessionTokenは一時証明書を用いてAWSのサービスAPIにアクセスする際に必須となる要素です。Credentialsクラスの仕様は下記になります。

・Credentials Class
http://docs.aws.amazon.com/sdkfornet/latest/apidocs/html/T_Amazon_SecurityToken_Model_Credentials.htm

まとめ

今回はAWS Security Tokenサービスから一時証明書を取得するプログラムをC#で記述してみました。一時証明書が取得出来ましたので、あとはこの証明書を利用してS3やEC2などにアクセスすることができます。また、今回ID管理サービスはモックでしたが、Active Directoryと連携するプログラムを書いても面白いでしょう(下記がAWS提供のサンプルです)

・Identity federation sample application for an Active Directory use case
http://aws.amazon.com/code/1288653099190193