CognitoのUserAttributesをC#から取得

Cognito C#言語から接続

Amazon Cognitoは、OpenID Connect などのエンタープライズ ID プロバイダーを通してサインインすることができるAWS内のサービスです。Cognitoのユーザープールにユーザーを追加すると、ユーザー内にUserAttributes情報を収納できます。そのCognito UserAttributesをC#言語を使ってユーザーにログインしUserAttributesを取得するコード例です。

パッケージインストール

Visual Studio C#で新規プロジェクトを作成し、下記のようにnugetからAWSSDKの必要なパッケージをインストールします

Install-Package AWSSDK.Core -Version 3.7.5.9
Install-Package AWSSDK.CognitoIdentity -Version 3.7.0.110 #←これは要らないかも
Install-Package AWSSDK.CognitoIdentityProvider -Version 3.7.1.82
Install-Package Amazon.Extensions.CognitoAuthentication -Version 2.2.2

AWSコンソール画面から[プールID]と[アプリクライアント ID]を用意

下のようにAWSコンソール画面(ブラウザ)などからユーザープールを選択し[プールID]と[アプリクライアントID]情報を取得します。

プールID取得方法
[ユーザープール]→[全般設定]→[プールID]
アプリクライアントID取得方法
[ユーザープール]→[アプリクライアント]→[アプリクライアントID]

コード例

usingで必要なのは下記の3行です

using Amazon;
using Amazon.CognitoIdentityProvider;
using Amazon.Extensions.CognitoAuthentication;
private void button1_Click(object sender, EventArgs e)
{
	string poolId = "ap-northeast-1_さきほど用意したプールID";
	string clientId = "さきほど用意したアプリクライアントID";
	string userId = textBox1.Text; //Cognitoでユーザー追加設定したユーザー名
	string passWd = textBox2.Text; //Cognitoでユーザー追加設定したパスワード
	AmazonCognitoIdentityProviderClient amazonCognitoIdentityProviderClient1 = new(new Amazon.Runtime.AnonymousAWSCredentials(), RegionEndpoint.APNortheast1);
	CognitoUserPool cognitoUserPool1 = new(poolId, clientId, amazonCognitoIdentityProviderClient1);
	CognitoUser cognitoUser1 = new(userId, clientId, cognitoUserPool1,amazonCognitoIdentityProviderClient1);

	InitiateSrpAuthRequest initiateSrpAuthRequest1 = new()
	{
		Password = passWd
	};
	var authResponse = cognitoUser1.StartWithSrpAuthAsync(initiateSrpAuthRequest1).ConfigureAwait(true).GetAwaiter();        
	var _idToken = authResponse.GetResult().AuthenticationResult;
	var _getUserResponse = cognitoUser1.GetUserDetailsAsync().ConfigureAwait(false).GetAwaiter();
	var _userResponse = _getUserResponse.GetResult();
	textBox3.Clear();
	_userResponse.UserAttributes.ForEach(_v => {
		textBox3.Text += string.Format("{0}={1}\r\n", _v.Name, _v.Value);
	});
}

async / awaitは利用していませんが、非同期処理実装も可能です。AWSSDKの場合GetAwaiter() / GetResult()を使います。

Amazon Cognito ユーザーデータ取得画面

API Gateway マッピングテンプレートでリモートIPなど取得する

API Gateway マッピングテンプレートでリモートIPなど取得

AWS API GatewayからDynamoDBテーブルに直接データを書き込む場合、

API Gatewayマッピングテンプレートを使います。その場合、リモートIPやUserAgentを取得するには$contextを利用し

テンプレートを下記のように記述します

{
  "TableName": "テーブル名",
  "Item": { 
    "sourceIp": {"S": "$context.identity.sourceIp" },
    "requestTime": {"S": "$context.requestTime"},
    "userAgent": {"S": "$context.identity.userAgent"},
    "hoge": {
      "S": "$input.params('hoge')"
    }
  }
}

https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html

Python AWS Lambda ModuleのPath指定

AWS Lambda PYTHONPATH

AWS LambdaPythonを動かす場合”PYTHONPATH“は「/var/runtime」になっているようで
下記コードを実行すると確認できます

import json
import os
def lambda_handler(event, context):
    PYTHONPATH = os.getenv('PYTHONPATH', '')
    print(PYTHONPATH)
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }

下記のコードを使ってsys.pathを確認すると

import json
import os
import sys
def lambda_handler(event, context):
    PYTHONPATH = sys.path
    print(PYTHONPATH)
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }

[‘/var/task’, ‘/opt/python/lib/python3.8/site-packages’, ‘/opt/python’, ‘/var/runtime’, ‘/var/lang/lib/python38.zip’, ‘/var/lang/lib/python3.8’, ‘/var/lang/lib/python3.8/lib-dynload’, ‘/var/lang/lib/python3.8/site-packages’, ‘/opt/python/lib/python3.8/site-packages’, ‘/opt/python’]配列で入っています

Lambdaの環境変数設定にPYTHONPATHを追加した

Lambdaの環境変数設定にPYTHONPATHを追加
Lambdaの環境変数設定にPYTHONPATHを追加

Lambdaを実行すると環境変数が予想通り設定できているように思うが違うようにも思える

['/var/task', '/var/runtime', '/var/task/lib', '/var/runtime', '/var/lang/lib/python38.zip', '/var/lang/lib/python3.8', '/var/lang/lib/python3.8/lib-dynload', '/var/lang/lib/python3.8/site-packages']

環境変数でのPYTHONPATH追加は大丈夫なのか?よくわからないのでPythonのコードに追加して確かめる

import json
import os
import sys
def lambda_handler(event, context):
    sys.path.append(os.path.join(os.path.dirname(__file__), 'lib2'))
    print(PYTHONPATH)
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }

lib2を追加した下記のようにlib2も追加されていた

[
	'/var/task', '/var/runtime', '/var/task/lib', '/var/runtime', '/var/lang/lib/python38.zip',
    '/var/lang/lib/python3.8', '/var/lang/lib/python3.8/lib-dynload',
    '/var/lang/lib/python3.8/site-packages', '/var/task/lib2'
]

PYTHONPATHとsys.pathがイコールなのかわからないけど同じようにも見える

結果:思ったことは、Lambda環境設定のPYTHONPATHに追加すればいい感じにしてくれるのかもしれない

pip3 インストール ターゲットpath指定

AWS Lambda Function内のlibにpip3インストールしたライブラリを入れたい場合下記のコマンドで可能です

pip3 install --target ./lib インストールしたいモジュール名