Help us understand the problem. What is going on with this article?

Windowsフォームアプリの認証にCognitoを使ってみた

More than 1 year has passed since last update.

概要

Cognitoで準備したアカウントを使ってWindows Formアプリにログインする。
ログインを通過したら、CognitoからAWSアカウント(S3 参照権限付き)をもらって
S3バケットの一覧を表示する。
ざっくり

前提

一連の認証ができる形をCognitoで作っておく↓
Cognito 組み込みWebページ+S3だけで動的サイトを作る

ここでは、以下のパラメータが必要になります

パラメータ
ユーザプールID us-east-1_hhogehogeh
アプリケーションクライアントID 4ks0na9rghogehogehoge0l
IDプールのID us-east-1:7864a4bf-8045-4221-a280-hogehogehoge

あと、S3のバケットも準備しておきます

ソース

フォームデザインは↓こんな感じ
Login.jpg

IDとパスワードを入力して、Loginボタンを押すと何かが起こる感じにしておきます。

Loginボタンクリック時は非同期で実行します。

/*
  ここで使う変数
 wwRegion :: Cognitoのリージョン
  wwUserPoolID  ::CognitoのユーザプールID
  wwAppClientID ::CognitoのアプリケーションクライアントID
  txtID.Text    ::フォーム上のIDテキストボックス
  txtPass.Text  ::フォーム上のPasswordテキストボックス
  wwIdPoolID    ::CognitoのIDプールのID
  wwS3BucketName::S3バケット名

*/

private async void btnLogin_ClickAsync(object sender, EventArgs e)
{
        AmazonCognitoIdentityProviderClient provider = new AmazonCognitoIdentityProviderClient(new Amazon.Runtime.AnonymousAWSCredentials(), wwRegion);
        CognitoUserPool userPool = new CognitoUserPool(wwUserPoolID, wwAppClientID, provider);
        CognitoUser user = new CognitoUser(txtID.Text, wwAppClientID, userPool, provider);
        InitiateSrpAuthRequest authRequest = new InitiateSrpAuthRequest()
        {
            Password = txtPass.Text
        };

        AuthFlowResponse authResponse = await user.StartWithSrpAuthAsync(authRequest).ConfigureAwait(false);
        string idToken = authResponse.AuthenticationResult.IdToken;

        CognitoAWSCredentials credentials = new CognitoAWSCredentials(
            wwIdPoolID, // ID プールの ID
            wwRegion    // リージョン
        );

        credentials.AddLogin("cognito-idp.us-east-1.amazonaws.com/" + wwUserPoolID, idToken); // the raw token
        //↓おまじない
        string hoge = await credentials.GetIdentityIdAsync();

        //ここから下は、通常のAPIの利用方法
        using (var client = new AmazonS3Client(credentials, wwRegion))
        {
            var S3Request = new ListObjectsRequest();
           S3Request.BucketName = wwS3BucketName;
            var S3Response = await client.ListObjectsAsync(S3Request);
            //ここでオブジェクトがとれている(略)

         }
}

解説

ちゃんと理解しているわけではないので、動物的感覚で説明

  1. 入力したユーザ+パスワードからトークンを取得
  2. トークンからAWSアカウントを取得
  3. AWSアカウントから、各種APIを利用する

1. 入力したID・パスワードから、トークンを取得する

公式:Amazon CognitoAuthentication 拡張ライブラリの例に書いているもの

        AmazonCognitoIdentityProviderClient provider = new AmazonCognitoIdentityProviderClient(new Amazon.Runtime.AnonymousAWSCredentials(), wwRegion);
        CognitoUserPool userPool = new CognitoUserPool(wwUserPoolID, wwAppClientID, provider);
        CognitoUser user = new CognitoUser(txtID.Text, wwAppClientID, userPool, provider);
        InitiateSrpAuthRequest authRequest = new InitiateSrpAuthRequest()
        {
            Password = txtPass.Text
        };

        AuthFlowResponse authResponse = await user.StartWithSrpAuthAsync(authRequest).ConfigureAwait(false);
        string idToken = authResponse.AuthenticationResult.IdToken;

トークンは、アクセストークン・IDトークン・他がある様子(詳しくはこちら)

ID・パスワードがCognitoで登録されているユーザに該当するとidTokenに、長い文字列が設定されます。

2. トークンを使ってAWS認可権限を取得する

フェデレーテッドアイデンティティ のサンプルコード→AWS認証情報の取得のソースコードを使います
スクリーンショット 2019-08-18 10.53.49.png

        CognitoAWSCredentials credentials = new CognitoAWSCredentials(
            wwIdPoolID, // ID プールの ID
            wwRegion    // リージョン
        );

credentialオブジェクトに、上記で取得したIDトークンを渡します。

        credentials.AddLogin("cognito-idp.us-east-1.amazonaws.com/" + wwUserPoolID, idToken);
        //↓おまじない
        string hoge = await credentials.GetIdentityIdAsync();

よくわからないが、おまじないをします。

ここで取得できるAWSアカウントは、👇これです
スクリーンショット

3.あとは、通常の認証と同じように使える

        using (var client = new AmazonS3Client(credentials, wwRegion))
        {
            var S3Request = new ListObjectsRequest();
           S3Request.BucketName = wwS3BucketName;
            var S3Response = await client.ListObjectsAsync(S3Request);
            //ここでオブジェクトがとれている(略)

         }

まとめ

.Net系はなかなか情報が見つからない。。
随時修正します。。

afukuma
AWS ソリューションアーキテクト 再現可能な小ネタを挙げます(GUI重視) VB.NET C# nodejs
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした