AWS Lambda を使用して ID プロバイダーを統合する - AWS Transfer Family

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

AWS Lambda を使用して ID プロバイダーを統合する

カスタム ID プロバイダーに接続する AWS Lambda 関数を作成します。Okta、Secrets Manager、、認証ロジックを含むカスタムデータストアなど OneLogin、任意のカスタム ID プロバイダーを使用できます。

注記

Lambda を ID プロバイダーとして使用する Transfer Family サーバーを作成する前に、関数を作成する必要があります。サンプルの Lambda 関数については、「Lambda 関数の例」を参照してください。または、 のいずれかを使用する CloudFormation スタックをデプロイできますLambda 関数のテンプレート。また、Lambda 関数が Transfer Family と信頼関係にあるリソースベースのポリシーを使用していることを確認してください。ポリシーの例については、「Lambda リソースベースのポリシー」を参照してください。

  1. AWS Transfer Family コンソールを開きます。

  2. [Create server] (サーバーの作成) を選択すると [Create server] (サーバーの作成) ページが開きます。[Choose an identity provider] (ID プロバイダーの選択) で [Custom Identity Provider] (カスタム ID プロバイダー) を選択します (次の画面例を参照)。

    [ID プロバイダーの選択] コンソールセクションで、[カスタム ID プロバイダー] が選択されています。また、ユーザーはパスワードまたはキーのいずれかを使用して認証できるというデフォルト値が選択されています。
    注記

    認証方法の選択は、Transfer Family サーバーのプロトコルの 1 つSFTPとして を有効にする場合にのみ使用できます。

  3. デフォルト値 AWS Lambda を使用して ID プロバイダー を接続します

  4. AWS Lambda 関数」では、Lambda 関数の名前を選択します。

  5. 残りのフィールドに値を入力してから [Create server] (サーバーの作成) を選択します。サーバーを作成するための残りの手順の詳細については、「SFTP、FTPS、またはFTPサーバーエンドポイントの設定」を参照してください。

Lambda リソースベースのポリシー

Transfer Family サーバーと Lambda を参照するポリシーが必要ですARNs。たとえば、ID プロバイダーに接続する Lambda 関数で次のポリシーを使用できます。ポリシーは文字列JSONとしてエスケープされます。

"Policy": "{ "Version": "2012-10-17", "Id": "default", "Statement": [ { "Sid": "AllowTransferInvocation", "Effect": "Allow", "Principal": { "Service": "transfer.amazonaws.com" }, "Action": "lambda:InvokeFunction", "Resource": "arn:aws:transfer:region:account-id:function:my-lambda-auth-function", "Condition": { "ArnLike": { "AWS:SourceArn": "arn:aws:transfer:region:account-id:server/server-id" } } } ] }"
注記

上記のポリシー例で、各 を置き換えます。user input placeholder 独自の情報。

イベントメッセージの構造

カスタムのオーソライザー Lambda 関数に送信されるSFTPサーバーからのイベントメッセージ構造IDPは次のとおりです。

{ 'username': 'value', 'password': 'value', 'protocol': 'SFTP', 'serverId': 's-abcd123456', 'sourceIp': '192.168.0.100' }

ここで、usernameおよびpasswordはサーバーに送信されるサインイン認証情報の値です。

例えば、以下のコマンドを入力して接続する:

sftp bobusa@server_hostname

その後、パスワードの入力を求められる:

Enter password: mysecretpassword

Lambda 関数内から渡されたイベントを出力することで、Lambda 関数からこれを確認できます。以下のテキストブロックのように見えるはずです。

{ 'username': 'bobusa', 'password': 'mysecretpassword', 'protocol': 'SFTP', 'serverId': 's-abcd123456', 'sourceIp': '192.168.0.100' }

イベント構造は FTPと で似ていますFTPS。唯一の違いは、これらの値が ではなく protocolパラメータに使用されることですSFTP。

認証用の Lambda 関数

さまざまな認証戦略を実装するには、Lambda 関数を編集します。アプリケーションのニーズを満たすために、 CloudFormation スタックをデプロイできます。Lambda の詳細については、AWS Lambda デベロッパーガイドまたは「Node.js による Lambda 関数の構築」を参照してください。

Lambda 関数のテンプレート

認証に Lambda 関数を使用する AWS CloudFormation スタックをデプロイできます。ログイン認証情報を使用してユーザーを認証および認可するテンプレートがいくつか用意されています。これらのテンプレートまたは AWS Lambda コードを変更して、ユーザーアクセスをさらにカスタマイズできます。

注記

テンプレートで FIPS対応のセキュリティポリシーを指定 AWS CloudFormation することで、 FIPSを通じて 対応 AWS Transfer Family サーバーを作成できます。使用可能なセキュリティポリシーについては、のセキュリティポリシー AWS Transfer Familyで説明しています。

認証に使用する AWS CloudFormation スタックを作成するには
  1. AWS CloudFormation コンソールを https://console.aws.amazon.com/cloudformation で開きます。

  2. 「 ユーザーガイド」の AWS CloudFormation 「スタックテンプレートの選択」の「既存のテンプレートからスタックをデプロイする手順に従います。 AWS CloudFormation

  3. 以下のテンプレートのいずれかを使用して、Transfer Family で認証に使用するLambda 関数を作成します。

    • クラシック (Amazon Cognito) スタックテンプレート

      でカスタム ID プロバイダーとして使用する AWS Lambda を作成するための基本的なテンプレート AWS Transfer Family。Amazon Cognito に対してパスワードベースの認証を行い、パブリックキーベースの認証が使用されている場合、パブリックキーは Amazon S3 バケットから返されます。デプロイ後に Lambda 関数コードを変更すれば異なる処理を実行できます。

    • AWS Secrets Manager スタックテンプレート

      を AWS Transfer Family サーバー AWS Lambda で使用する基本的なテンプレートで、Secrets Manager を ID プロバイダーとして統合します。形式の AWS Secrets Manager のエントリに対して認証されますaws/transfer/server-id/username。さらに、シークレットは、Transfer Family に返されるすべてのユーザープロパティのキーバリューペアを保持する必要があります。デプロイ後に Lambda 関数コードを変更すれば異なる処理を実行できます。

    • Okta スタックテンプレート : を AWS Transfer Family サーバー AWS Lambda と使用して Okta をカスタム ID プロバイダーとして統合する基本的なテンプレート。

    • Okta-mfa スタックテンプレート : を AWS Transfer Family サーバー AWS Lambda で使用する基本テンプレートで、カスタム ID プロバイダーとして Okta を MultiFactor Authentication と統合します。

    • Azure Active Directory テンプレート : このスタックの詳細については、ブログ記事「Azure Active Directory と AWS Transfer Family による の認証 AWS Lambda」で説明されています。

    スタックがデプロイされたら、 CloudFormation コンソールの出力タブでスタックの詳細を表示できます。

    これらのスタックのいずれかをデプロイすることが、カスタム ID プロバイダーをTransfer Family ワークフローに統合するうえで最も簡単な方法です。

有効な Lambda 値

次の表は、カスタム ID プロバイダーに使用される Lambda 関数について Transfer Family が受け入れる値の詳細についての説明です。

説明 必須

Role

Amazon S3 バケットまたは Amazon EFS ファイルシステムへのユーザーのアクセスを制御するIAMロールの Amazon リソースネーム (ARN) を指定します。 Amazon S3 このロールにアタッチされたポリシーは、Amazon S3 または Amazon EFS ファイルシステムとの間でファイルを転送する際にユーザーに提供するアクセスレベルを決定します。IAM ロールには、ユーザーの転送リクエストを処理するときにサーバーがリソースにアクセスできるようにする信頼関係も含める必要があります。

信頼関係の確立の詳細については、信頼関係を確立するには を参照してください。

必須

PosixProfile

ユーザー ID (Uid)、グループ ID (Gid)、および Amazon EFS ファイルシステムへのユーザーのアクセスを制御する任意のセカンダリグループ IDs (SecondaryGids) を含む完全な POSIX ID。ファイルシステム内のファイルとディレクトリに設定されたPOSIXアクセス許可により、Amazon EFS ファイルシステムとの間でファイルを転送する際にユーザーが得るアクセスレベルが決まります。

Amazon EFS バッキングストレージに必要です

PublicKeys

このユーザーに有効なSSHパブリックキー値のリスト。空のリストはこれが有効なログインではないことを示します。パスワード認証中に返してはなりません。

オプションです。

Policy

複数のユーザーで同じIAMロールを使用できるように、ユーザーのセッションポリシー。このポリシーは、ユーザーアクセスのスコープを Amazon S3 バケットの一部に絞り込みます。

オプションです。

HomeDirectoryType

ユーザーがサーバーにログインするときにホームディレクトリにするランディングディレクトリ (フォルダ) のタイプ。

  • に設定するとPATH、ユーザーはファイル転送プロトコルクライアントに絶対 Amazon S3 バケットまたは Amazon EFSパスをそのまま表示します。

  • に設定する場合はLOGICALHomeDirectoryDetailsパラメータにマッピングを指定してAmazon S3または Amazon EFSパスをユーザーに表示する必要があります。

オプションです。

HomeDirectoryDetails

ユーザーに表示させる Amazon S3 または Amazon EFSパスとキーと、表示方法を指定する論理ディレクトリマッピング。EntryTargetペアを指定する必要があります。 はパスがどのように表示されるかEntryを示し、 Target は実際の Amazon S3 または Amazon EFSパスです。

HomeDirectoryTypeLOGICAL の値がある場合に必須

HomeDirectory

ユーザーがクライアントを使用してサーバーにログインするときの、ユーザーのランディングディレクトリ。

オプションです。

注記

HomeDirectoryDetails はマップの文字列表現ですJSON。これは、実際のJSONマップオブジェクトでありPosixProfile、文字列のJSON配列PublicKeysである とは対照的です。言語固有の詳細については、コード例を参照してください。

Lambda 関数の例

このセクションでは、NodeJS と Python の両方で使用される Lambda 関数の例をいくつか紹介します。

注記

これらの例では、ユーザー、ロール、POSIXプロファイル、パスワード、ホームディレクトリの詳細がすべて例であり、実際の値に置き換える必要があります。

Logical home directory, NodeJS

以下の NodeJS サンプル関数は、「論理ホームディレクトリ」を持つユーザーの詳細を提供します。

// GetUserConfig Lambda exports.handler = (event, context, callback) => { console.log("Username:", event.username, "ServerId: ", event.serverId); var response; // Check if the username presented for authentication is correct. This doesn't check the value of the server ID, only that it is provided. if (event.serverId !== "" && event.username == 'example-user') { var homeDirectoryDetails = [ { Entry: "/", Target: "/fs-faa1a123" } ]; response = { Role: 'arn:aws:iam::123456789012:role/transfer-access-role', // The user is authenticated if and only if the Role field is not blank PosixProfile: {"Gid": 65534, "Uid": 65534}, // Required for EFS access, but not needed for S3 HomeDirectoryDetails: JSON.stringify(homeDirectoryDetails), HomeDirectoryType: "LOGICAL", }; // Check if password is provided if (!event.password) { // If no password provided, return the user's SSH public key response['PublicKeys'] = [ "ssh-rsa abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789" ]; // Check if password is correct } else if (event.password !== 'Password1234') { // Return HTTP status 200 but with no role in the response to indicate authentication failure response = {}; } } else { // Return HTTP status 200 but with no role in the response to indicate authentication failure response = {}; } callback(null, response); };
Path-based home directory, NodeJS

以下の NodeJS サンプル関数は、パスベースのホーム・ディレクトリを持つユーザーの詳細を提供します。

// GetUserConfig Lambda exports.handler = (event, context, callback) => { console.log("Username:", event.username, "ServerId: ", event.serverId); var response; // Check if the username presented for authentication is correct. This doesn't check the value of the server ID, only that it is provided. // There is also event.protocol (one of "FTP", "FTPS", "SFTP") and event.sourceIp (e.g., "127.0.0.1") to further restrict logins. if (event.serverId !== "" && event.username == 'example-user') { response = { Role: 'arn:aws:iam::123456789012:role/transfer-access-role', // The user is authenticated if and only if the Role field is not blank Policy: '', // Optional, JSON stringified blob to further restrict this user's permissions HomeDirectory: '/fs-faa1a123' // Not required, defaults to '/' }; // Check if password is provided if (!event.password) { // If no password provided, return the user's SSH public key response['PublicKeys'] = [ "ssh-rsa abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789" ]; // Check if password is correct } else if (event.password !== 'Password1234') { // Return HTTP status 200 but with no role in the response to indicate authentication failure response = {}; } } else { // Return HTTP status 200 but with no role in the response to indicate authentication failure response = {}; } callback(null, response); };
Logical home directory, Python

以下の Python サンプル関数は、「論理ホームディレクトリ」を持つユーザーの詳細を提供します。

# GetUserConfig Python Lambda with LOGICAL HomeDirectoryDetails import json def lambda_handler(event, context): print("Username: {}, ServerId: {}".format(event['username'], event['serverId'])) response = {} # Check if the username presented for authentication is correct. This doesn't check the value of the server ID, only that it is provided. if event['serverId'] != '' and event['username'] == 'example-user': homeDirectoryDetails = [ { 'Entry': '/', 'Target': '/fs-faa1a123' } ] response = { 'Role': 'arn:aws:iam::123456789012:role/transfer-access-role', # The user will be authenticated if and only if the Role field is not blank 'PosixProfile': {"Gid": 65534, "Uid": 65534}, # Required for EFS access, but not needed for S3 'HomeDirectoryDetails': json.dumps(homeDirectoryDetails), 'HomeDirectoryType': "LOGICAL" } # Check if password is provided if event.get('password', '') == '': # If no password provided, return the user's SSH public key response['PublicKeys'] = [ "ssh-rsa abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789" ] # Check if password is correct elif event['password'] != 'Password1234': # Return HTTP status 200 but with no role in the response to indicate authentication failure response = {} else: # Return HTTP status 200 but with no role in the response to indicate authentication failure response = {} return response
Path-based home directory, Python

以下の Python サンプル関数は、パスベースのホームディレクトリを持つユーザーの詳細を提供します。

# GetUserConfig Python Lambda with PATH HomeDirectory def lambda_handler(event, context): print("Username: {}, ServerId: {}".format(event['username'], event['serverId'])) response = {} # Check if the username presented for authentication is correct. This doesn't check the value of the server ID, only that it is provided. # There is also event.protocol (one of "FTP", "FTPS", "SFTP") and event.sourceIp (e.g., "127.0.0.1") to further restrict logins. if event['serverId'] != '' and event['username'] == 'example-user': response = { 'Role': 'arn:aws:iam::123456789012:role/transfer-access-role', # The user will be authenticated if and only if the Role field is not blank 'Policy': '', # Optional, JSON stringified blob to further restrict this user's permissions 'HomeDirectory': '/fs-fs-faa1a123', 'HomeDirectoryType': "PATH" # Not strictly required, defaults to PATH } # Check if password is provided if event.get('password', '') == '': # If no password provided, return the user's SSH public key response['PublicKeys'] = [ "ssh-rsa abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789" ] # Check if password is correct elif event['password'] != 'Password1234': # Return HTTP status 200 but with no role in the response to indicate authentication failure response = {} else: # Return HTTP status 200 but with no role in the response to indicate authentication failure response = {} return response

設定をテストする

カスタム ID プロバイダーを作成したら、設定をテストする必要があります。

Console
AWS Transfer Family コンソールを使用して設定をテストするには
  1. AWS Transfer Family コンソールを開きます。

  2. [Servers] (サーバー) ページで新しいサーバーを選択し、[Actions] (アクション) を選択してから [Test] (テスト) を選択します。

  3. AWS CloudFormation スタックをデプロイしたときに設定したユーザー名とパスワードのテキストを入力します。デフォルトのオプションのままだと、ユーザー名は myuser、パスワードは MySuperSecretPassword となります。

  4. AWS CloudFormation スタックをデプロイするときに設定する場合は、サーバープロトコルを選択し、ソース IP の IP アドレスを入力します。

CLI
を使用して設定をテストするには AWS CLI
  1. test-identity-provider コマンドを実行します。以降のステップで説明するように、それぞれの user input placeholder を独自の情報に置き換えます。

    aws transfer test-identity-provider --server-id s-1234abcd5678efgh --user-name myuser --user-password MySuperSecretPassword --server-protocol FTP --source-ip 127.0.0.1
  2. サーバー ID を入力します。

  3. AWS CloudFormation スタックをデプロイしたときに設定したユーザー名とパスワードを入力します。デフォルトのオプションのままだと、ユーザー名は myuser、パスワードは MySuperSecretPassword となります。

  4. AWS CloudFormation スタックをデプロイするときに設定する場合は、サーバープロトコルとソース IP アドレスを入力します。

ユーザー認証が成功すると、テストはStatusCode: 200HTTPレスポンス、空の文字列 Message: "" (それ以外の場合は失敗の理由を含む)、および Response フィールドを返します。

注記

以下のレスポンス例では、 Response フィールドは「文字列化」 (プログラム内で使用できるフラットJSON文字列に変換) されたJSONオブジェクトであり、ユーザーのロールとアクセス許可の詳細が含まれています。

{ "Response":"{\"Policy\":\"{\\\"Version\\\":\\\"2012-10-17\\\",\\\"Statement\\\":[{\\\"Sid\\\":\\\"ReadAndListAllBuckets\\\",\\\"Effect\\\":\\\"Allow\\\",\\\"Action\\\":[\\\"s3:ListAllMybuckets\\\",\\\"s3:GetBucketLocation\\\",\\\"s3:ListBucket\\\",\\\"s3:GetObjectVersion\\\",\\\"s3:GetObjectVersion\\\"],\\\"Resource\\\":\\\"*\\\"}]}\",\"Role\":\"arn:aws:iam::000000000000:role/MyUserS3AccessRole\",\"HomeDirectory\":\"/\"}", "StatusCode": 200, "Message": "" }