

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

# カスタム ID プロバイダーの使用
<a name="custom-idp-intro"></a>

AWS Transfer Family には、カスタム ID プロバイダーが安全なファイル転送のためにユーザーを認証および認可するためのいくつかのオプションが用意されています。主なアプローチは次のとおりです。
+ [カスタム ID プロバイダーソリューション](custom-idp-toolkit.md)— このトピックでは、GitHub でホストされているツールキットを使用して、Transfer Family カスタム ID プロバイダーソリューションについて説明します。
**注記**  
ほとんどのユースケースでは、これは推奨されるオプションです。具体的には、100 を超える Active Directory グループをサポートする必要がある場合、カスタム ID プロバイダーソリューションは、グループの制限なしにスケーラブルな代替手段を提供します。このソリューションは、ブログ記事[「カスタム ID プロバイダーによる Active Directory 認証の簡素化 AWS Transfer Family](https://aws.amazon.com/blogs/storage/simplify-active-directory-authentication-with-a-custom-identity-provider-for-aws-transfer-family/)」で説明されています。
+ [Amazon API Gateway を使用して ID プロバイダーを統合する](authentication-api-gateway.md)— このトピックでは、 AWS Lambda 関数を使用して Amazon API Gateway メソッドをバックアップする方法について説明します。

  RESTful インターフェイスは、単一の Amazon API Gateway メソッドで提供できます。Transfer Family は、このメソッドを呼び出して ID プロバイダーに接続し、ID プロバイダーは Amazon S3 または Amazon EFS へのアクセスを認証および承認します。ID プロバイダーを統合するために RESTful API が必要な場合、または AWS WAF を使用してその機能をジオブロッキングまたはレート制限リクエストに活用する場合は、このオプションを使用します。詳細については、「[Amazon API Gateway を使用して ID プロバイダーを統合する](authentication-api-gateway.md)」を参照してください。
+ [動的なアクセス許可管理アプローチ](dynamic-permission-management.md)— このトピックでは、セッションポリシーを使用してユーザーアクセス許可を動的に管理する方法について説明します。

  ユーザーを認証するには、 AWS Transfer Familyで既存の ID プロバイダーを使用します。ID プロバイダーを統合するには、 AWS Lambda 関数を使用して、Amazon S3 または Amazon Elastic File System (Amazon EFS) へのアクセス権を認証および承認します。詳細については、「[AWS Lambda を使用して ID プロバイダーを統合する](custom-lambda-idp.md)」を参照してください。また、 AWS Transfer Family Management Console では、ファイル数や転送バイト数などのメトリクスに関する CloudWatch グラフにアクセスすることができ、一元化されたダッシュボードを使用してファイル転送を監視するための単一ペインを提供します。
+ Transfer Family は、ブログ投稿と、ファイル転送ソリューションの構築を案内するワークショップを提供します。このソリューションは、 AWS Transfer Family マネージド SFTP/FTPS エンドポイントに 、ユーザー管理に Amazon Cognito と DynamoDB を活用します。

  ブログ記事は、 [AWS Transfer Family および Amazon S3 での ID プロバイダーとしての Amazon Cognito Amazon S3](https://aws.amazon.com/blogs/storage/using-amazon-cognito-as-an-identity-provider-with-aws-transfer-family-and-amazon-s3/)の使用で入手できます。ワークショップの詳細については、[こちらを参照してください](https://catalog.workshops.aws/transfer-family-sftp/en-US)。

**注記**  
カスタム ID プロバイダーの場合、ユーザー名は 3 ～ 100 文字である必要があります。ユーザー名には、a～z、A～Z、0～9、アンダースコア「\$1」、ハイフン「-」、ピリオド「.」、アットマーク「@」を使用できます。ユーザー名は、ハイフン '-'、ピリオド '.'、またはアットマーク '@' で始めることはできません。

カスタム ID プロバイダーを実装するときは、次のベストプラクティスを考慮してください。
+ Transfer Family サーバーと同じ AWS アカウント およびリージョンにソリューションをデプロイします。
+ IAM ロールとポリシーを設定するときに、最小特権の原則を実装します。
+ セキュリティを強化するために、IP 許可リストや標準化されたログ記録などの機能を使用します。
+ デプロイ前に、非本番環境でカスタム ID プロバイダーを徹底的にテストします。

**Topics**
+ [カスタム ID プロバイダーソリューション](custom-idp-toolkit.md)
+ [AWS Lambda を使用して ID プロバイダーを統合する](custom-lambda-idp.md)
+ [Amazon API Gateway を使用して ID プロバイダーを統合する](authentication-api-gateway.md)
+ [複数の認証方法の使用](custom-idp-mfa.md)
+ [カスタム ID プロバイダーの IPv6 サポート](custom-idp-ipv6.md)

# カスタム ID プロバイダーソリューション
<a name="custom-idp-toolkit"></a>

 AWS Transfer Family カスタム ID プロバイダーソリューションは、サービスを実装する際に企業が持つ多くの一般的な認証と認可のユースケースを解決するモジュール式のカスタム ID プロバイダーソリューションです。このソリューションは、ユーザーごとの詳細なセッション設定でカスタム ID プロバイダーを実装するための再利用可能な基盤を提供し、認証ロジックと認可ロジックを分離して、さまざまなユースケース向けに柔軟でeasy-to-maintain基盤を提供します。

 AWS Transfer Family カスタム ID プロバイダーソリューションを使用すると、一般的なエンタープライズ認証と認可のユースケースに対処できます。このモジュラーソリューションは以下を提供します。
+ カスタム ID プロバイダーを実装するための再利用可能な基盤 
+ ユーザーごとの詳細なセッション設定 
+ 認証ロジックと認可ロジックを分離 

## カスタム ID ツールキットの実装の詳細
<a name="idp-toolkit-implementation-details"></a>

このソリューションは、さまざまなユースケースに柔軟で保守可能なベースを提供します。開始するには、[https://github.com/aws-samples/toolkit-for-aws-transfer-family](https://github.com/aws-samples/toolkit-for-aws-transfer-family) でツールキットを確認し、[「開始方法](https://github.com/aws-samples/toolkit-for-aws-transfer-family/tree/main/solutions/custom-idp#getting-started)」セクションのデプロイ手順に従ってください。

![\[GitHub で利用可能なカスタム ID プロバイダーツールキットのアーキテクチャ図。\]](http://docs.aws.amazon.com/ja_jp/transfer/latest/userguide/images/custom-idp-solution-high-level-architecture.png)


**注記**  
カスタム ID プロバイダーのテンプレートと例を以前に使用したことがある場合は、代わりにこのソリューションを採用することを検討してください。今後、プロバイダー固有のモジュールはこのソリューションで標準化されます。このソリューションには、継続的なメンテナンスと機能強化が適用されます。

このソリューションには、 `HomeDirectoryDetails`パラメータなど AWS Transfer Family、ログ記録や必要な追加のセッションメタデータの保存先などの詳細を説明するカスタムプロバイダーを実装するための標準パターンが含まれています。このソリューションは、ユーザーごとの詳細なセッション設定でカスタム ID プロバイダーを実装するための再利用可能な基盤を提供し、認証を完了してセッションの設定を確立するために Transfer Family に返される設定を構築する再利用可能なロジックから ID プロバイダー認証ロジックを切り離します。

このソリューションのコードとサポートリソースは、[https://github.com/aws-samples/toolkit-for-aws-transfer-family](https://github.com/aws-samples/toolkit-for-aws-transfer-family) で入手できます。

ツールキットには次の機能が含まれています。
+ 必要なリソースをプロビジョニングする[AWS Serverless Application Model](https://aws.amazon.com/serverless/sam)テンプレート。必要に応じて、ブログ記事「Securing with Web Application Firewall and Amazon API Gateway」で説明されているように AWS WAF、Amazon API Gateway をデプロイして設定します。 [AWS Transfer FamilyAWS Amazon API Gateway](https://aws.amazon.com/blogs/storage/securing-aws-transfer-family-with-aws-web-application-firewall-and-amazon-api-gateway/)
+ `HomeDirectoryDetails`、、 などのユーザーセッション設定など、ID プロバイダーに関する設定メタデータを保存する [Amazon DynamoDB](https://aws.amazon.com/dynamodb) スキーマ`Policy`。 `Role`
+ モジュールとして、将来的に新しい ID プロバイダーをソリューションに追加できるモジュラーアプローチ。
+ 属性の取得: 必要に応じて、AD、LDAP、Okta などのサポートされている ID プロバイダーから IAM ロールと POSIX プロファイル (UID と GID) 属性を取得します。
+ ソリューションの同じデプロイを使用して、単一の Transfer Family サーバーと複数の Transfer Family サーバーに接続された複数の ID プロバイダーのサポート。
+ ユーザーごとまたは ID プロバイダーごとにオプションで設定できる IP 許可リストなどの組み込み IP 許可リストチェック。
+ 詳細なログ記録と設定可能なログレベル、およびトラブルシューティングに役立つトレースのサポート。

カスタム ID プロバイダーソリューションをデプロイする前に、次の AWS リソースが必要です。
+ NAT ゲートウェイまたは DynamoDB ゲートウェイエンドポイントを介したインターネット接続を備えた、プライベートサブネットを持つ Amazon Virtual Private Cloud (VPC)。
+ 以下のタスクを実行するための適切な IAM アクセス許可。
  + `custom-idp.yaml` CloudFormation テンプレートをデプロイします。
  +  AWS CodePipeline プロジェクトの作成
  +  AWS CodeBuild プロジェクトを作成する
  + IAM ロールとポリシーを作成する

**重要**  
ターゲット Transfer Family サーバー AWS リージョン を含む同じ AWS アカウント および にソリューションをデプロイする必要があります。

## サポートされている ID プロバイダー
<a name="custom-supported-idp"></a>

次のリストには、カスタム ID プロバイダーソリューションでサポートされている ID プロバイダーの詳細が含まれています。


| プロバイダー | パスワードフロー | パブリックキーフロー | 多要素 | 属性の取得 | 詳細 | 
| --- | --- | --- | --- | --- | --- | 
| Active Directory と LDAP | はい  | あり | なし | はい | ユーザー検証は、パブリックキー認証フローの一部として実行できます。 | 
| Argon2 (ローカルハッシュ) | はい | なし | なし | いいえ | Argon2 ハッシュは、「ローカル」パスワードベースの認証ユースケースのユーザーレコードに保存されます。 | 
| Amazon Cognito | あり | なし | はい\$1 | いいえ | 時間ベースのワンタイムパスワード (TOTP) ベースの多要素認証のみ。 \$1SMS ベースの MFA はサポートされていません。 | 
| Entra ID (以前の Azure AD) | はい | なし | なし | いいえ |  | 
| Okta | はい  | はい | はい\$1 | はい | TOTP ベースの MFA のみ。 | 
| パブリックキー | いいえ | あり | なし | いいえ | パブリックキーは DynamoDB のユーザーレコードに保存されます。 | 
| Secrets Manager | はい  | あり | なし | いいえ |  | 

# AWS Lambda を使用して ID プロバイダーを統合する
<a name="custom-lambda-idp"></a>

このトピックでは、カスタム ID プロバイダーに接続する AWS Lambda 関数を作成する方法について説明します。Okta、Secrets Manager、OneLogin や、認可および認証ロジックを含むカスタムデータストアなど、任意のカスタム ID プロバイダーを使用できます。

ほとんどのユースケースでは、カスタム ID プロバイダーを設定する推奨方法は、 を使用することです[カスタム ID プロバイダーソリューション](custom-idp-toolkit.md)。

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

1. [AWS Transfer Family コンソール](https://console.aws.amazon.com/transfer/)を開きます。

1. [**Create server**] (サーバーの作成) を選択すると [**Create server**] (サーバーの作成) ページが開きます。[**Choose an identity provider**] (ID プロバイダーの選択) で [**Custom Identity Provider**] (カスタム ID プロバイダー) を選択します (次の画面例を参照)。  
![\[[ID プロバイダーの選択] コンソールセクションで、[カスタム ID プロバイダー] が選択されています。また、ユーザーはパスワードまたはキーのいずれかを使用して認証できるというデフォルト値が選択されています。\]](http://docs.aws.amazon.com/ja_jp/transfer/latest/userguide/images/custom-lambda-console.png)
**注記**  
認証方法を選択できるのは、Transfer Familyサーバーのプロトコルの1つとしてSFTPを有効にした場合のみです。

1. デフォルト値である ** AWS Lambda を使用して ID プロバイダーを接続します**。

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

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

## Lambda リソースベースのポリシー
<a name="lambda-resource-policy"></a>

Transfer Family サーバーと Lambda ARN を参照するポリシーが必要です。たとえば、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:lambda:region:123456789012:function:my-lambda-auth-function\",
  \"Condition\":{\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:transfer:region:123456789012:server/server-id\"}}}
]}"
```

**注記**  
上記のポリシー例では、各「*ユーザー入力プレースホルダー*」をあなた自身の情報で置き換えます。

## イベントメッセージの構造
<a name="event-message-structure"></a>

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

```
{
    "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 で似ています。唯一の違いは、SFTP ではなく、これらの値が`protocol`パラメータに使用されることです。

## 認証用の Lambda 関数
<a name="authentication-lambda-examples"></a>

さまざまな認証戦略を実装するには、Lambda 関数を編集します。アプリケーションのニーズを満たすために、CloudFormation スタックをデプロイできます。Lambda の詳細については、[AWS Lambda デベロッパーガイド](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html)または「[Node.js による Lambda 関数の構築](https://docs.aws.amazon.com/lambda/latest/dg/lambda-nodejs.html)」を参照してください。

**Topics**
+ [有効な Lambda 値](#lambda-valid-values)
+ [Lambda 関数の例](#lambda-auth-examples)
+ [設定をテストする](#authentication-test-configuration)
+ [Lambda 関数のテンプレート](#lambda-idp-templates)

### 有効な Lambda 値
<a name="lambda-valid-values"></a>

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


|  値  |  説明  |  必須  | 
| --- | --- | --- | 
|  `Role`  |  Amazon S3 バケットまたは Amazon EFS ファイルシステムへのユーザーのアクセスを制御する IAM ロールの Amazon Resource Name (ARN) を指定します。このロールにアタッチされたポリシーにより、ファイルを Amazon S3 または Amazon EFS ファイルシステム間で転送する際のユーザーに付与するアクセスのレベルが決定されます。IAM ロールには、ユーザーの転送リクエストを処理する際に、サーバーによるリソースへのアクセスを許可する信頼関係も含まれる必要があります。 信頼関係の確立の詳細については、[信頼関係を確立するには](requirements-roles.md#establish-trust-transfer) を参照してください。  |  必須  | 
|  `PosixProfile`  |  ユーザーの Amazon EFS ファイルシステムへのアクセスを制御する、ユーザー ID (`Uid`)、グループ ID (`Gid`)、およびセカンダリグループ ID (`SecondaryGids`) を含む完全な POSIX ID。ファイルシステム内のファイルとディレクトリに設定される POSIX アクセス許可によって、Amazon EFS ファイルシステムとの間でファイルを転送するときにユーザーが得るアクセスのレベルが決まります。  |  Amazon EFS バッキングストレージに必須  | 
|  `PublicKeys`  |  このユーザーに有効な SSH パブリックキー値のリスト。空のリストはこれが有効なログインではないことを示します。パスワード認証中に返してはなりません。  |  オプションです。  | 
|  `Policy`  |  複数のユーザーに同じ IAM ロールの使用を可能にするユーザーのセッションポリシー。このポリシーは、ユーザーアクセスのスコープを Amazon S3 バケットの一部に絞り込みます。カスタム ID プロバイダーでセッションポリシーを使用する方法の詳細については、このトピックのセッションポリシーの例を参照してください。  |  オプションです。  | 
|  `HomeDirectoryType`  |  ユーザーがサーバーにログインするときにホームディレクトリにするランディングディレクトリ (フォルダ) のタイプ。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/transfer/latest/userguide/custom-lambda-idp.html)  |  オプションです。  | 
|  `HomeDirectoryDetails`  |  ユーザーに表示する Amazon S3 または Amazon EFS のパスとキー、およびそれらをどのように表示するかを指定する論理ディレクトリマッピング。「`Entry`」と「`Target`」のペアを指定する必要があり、`Entry` はパスの表示方法を示し、`Target` は実際の Amazon S3 または Amazon EFS のパスです。  |  `HomeDirectoryType` に `LOGICAL` の値がある場合に必須  | 
|  `HomeDirectory`  |  ユーザーがクライアントを使用してサーバーにログインするときの、ユーザーのランディングディレクトリ。形式はストレージバックエンドによって異なります。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/transfer/latest/userguide/custom-lambda-idp.html)  バケット名または Amazon EFS ファイルシステム ID をパスに含める必要があります。この情報を省略すると、ファイル転送中に「ファイルが見つかりません」エラーが発生します。   |  オプションです。  | 

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

**HomeDirectory 形式の要件**  
`HomeDirectory` パラメータを使用する場合は、完全なパス形式を含めてください。  
**Amazon S3 ストレージの場合:** バケット名は常に 形式で含めます。 `/bucket-name/path`
**Amazon EFS ストレージの場合:** ファイルシステム ID は必ず 形式で含めます。 `/fs-12345/path`
「ファイルが見つかりません」エラーの一般的な原因は、`HomeDirectory`パスからバケット名または EFS ファイルシステム ID を省略することです。ストレージ識別子`/`なしで `HomeDirectory`に設定すると、認証は成功しますが、ファイルオペレーションは失敗します。

### Lambda 関数の例
<a name="lambda-auth-examples"></a>

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

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

------
#### [ Logical home directory, NodeJS ]

以下の NodeJS サンプル関数は、「[論理ホームディレクトリ](https://docs.aws.amazon.com/transfer/latest/userguide/logical-dir-mappings.html)」を持つユーザーの詳細を提供します。

```
// 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 format depends on your storage backend:
      // For S3: '/bucket-name/user-home-directory' (e.g., '/my-transfer-bucket/users/john')
      // For EFS: '/fs-12345/user-home-directory' (e.g., '/fs-faa1a123/users/john')
      HomeDirectory: '/my-transfer-bucket/users/example-user' // S3 example - replace with your bucket name
      // HomeDirectory: '/fs-faa1a123/users/example-user' // EFS example - uncomment for EFS
    };
    
    // 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 サンプル関数は、「[論理ホームディレクトリ](https://docs.aws.amazon.com/transfer/latest/userguide/logical-dir-mappings.html)」を持つユーザーの詳細を提供します。

```
# 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 format depends on your storage backend:
      # For S3: '/bucket-name/user-home-directory' (e.g., '/my-transfer-bucket/users/john')
      # For EFS: '/fs-12345/user-home-directory' (e.g., '/fs-faa1a123/users/john')
      'HomeDirectory': '/my-transfer-bucket/users/example-user', # S3 example - replace with your bucket name
      # 'HomeDirectory': '/fs-faa1a123/users/example-user', # EFS example - uncomment for EFS
      '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
```

------

### 設定をテストする
<a name="authentication-test-configuration"></a>

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

------
#### [ Console ]

**AWS Transfer Family コンソールを使用して設定をテストするには**

1. [AWS Transfer Family コンソール](https://console.aws.amazon.com/transfer/)を開きます。

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

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

1.  CloudFormation スタックのデプロイ時に設定する場合は、**サーバープロトコル**を選択し、**送信元 IP の IP** アドレスを入力します。

------
#### [ CLI ]

**AWS CLI を使用して設定をテストするには**

1. [test-identity-provider](https://docs.aws.amazon.com/cli/latest/reference/transfer/test-identity-provider.html) コマンドを実行します。以降のステップで説明するように、それぞれの `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
   ```

1. サーバー ID を入力します。

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

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

------

ユーザー認証が成功した場合、テストは`StatusCode: 200` HTTP レスポンス、空の文字列`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": ""
}
```

### Lambda 関数のテンプレート
<a name="lambda-idp-templates"></a>

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

**注記**  
テンプレートで FIPS 対応セキュリティポリシーを指定 CloudFormation することで、 を使用して FIPS 対応 AWS Transfer Family サーバーを作成できます。使用可能なセキュリティポリシーについては、[AWS Transfer Family サーバーのセキュリティポリシー](security-policies.md)で説明しています。

**認証に使用する CloudFormation スタックを作成するには**

1. [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) で CloudFormation コンソールを開きます。

1. 「 *AWS CloudFormation ユーザーガイド*」の CloudFormation 「スタックテンプレート[の選択」の「既存のテンプレートからスタックを](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-using-console-create-stack-template.html)デプロイする手順」に従います。

1. 以下のテンプレートのいずれかを使用して、Transfer Family で認証に使用するLambda 関数を作成します。
   + [クラシック (Amazon Cognito) スタックテンプレート](https://s3.amazonaws.com/aws-transfer-resources/custom-idp-templates/aws-transfer-custom-idp-basic-lambda-cognito-s3.template.yml)

     でカスタム ID プロバイダーとして使用する AWS Lambda を作成するための基本的なテンプレート AWS Transfer Family。Amazon Cognito に対してパスワードベースの認証を行い、パブリックキーベースの認証が使用されている場合、パブリックキーは Amazon S3 バケットから返されます。デプロイ後に Lambda 関数コードを変更すれば異なる処理を実行できます。
   + [AWS Secrets Manager スタックテンプレート](https://s3.amazonaws.com/aws-transfer-resources/custom-idp-templates/aws-transfer-custom-idp-secrets-manager-lambda.template.yml)

     と AWS Transfer Family サーバー AWS Lambda を使用して Secrets Manager を ID プロバイダーとして統合する基本的なテンプレート。形式の AWS Secrets Manager のエントリに対して認証されます`aws/transfer/server-id/username`。さらに、シークレットは、Transfer Family に返されるすべてのユーザープロパティのキーバリューペアを保持する必要があります。デプロイ後に Lambda 関数コードを変更すれば異なる処理を実行できます。
   + [Okta スタックテンプレート](https://s3.amazonaws.com/aws-transfer-resources/custom-idp-templates/aws-transfer-custom-idp-okta-lambda.template.yml): を AWS Transfer Family サーバー AWS Lambda で使用する基本テンプレートで、Okta をカスタム ID プロバイダーとして統合します。
   + [Okta-mfa スタックテンプレート](https://s3.amazonaws.com/aws-transfer-resources/custom-idp-templates/aws-transfer-custom-idp-okta-mfa-lambda.template.yml): を AWS Transfer Family サーバー AWS Lambda で使用する基本テンプレートで、カスタム ID プロバイダーとして Okta を多要素認証と統合します。
   + [ Azure Active Directory テンプレート](https://s3.amazonaws.com/aws-transfer-resources/custom-idp-templates/aws-transfer-custom-idp-basic-lambda-azure-ad.template.yml): このスタックの詳細については、ブログ記事[「Authenticating to AWS Transfer Family with Azure Active Directory and AWS Lambda](https://aws.amazon.com/blogs/storage/authenticating-to-aws-transfer-family-with-azure-active-directory-and-aws-lambda/)」を参照してください。

   スタックのデプロイ後には、CloudFormation コンソールの [**Output**] (出力) にタブにスタックについての詳細が表示されます。

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

# Amazon API Gateway を使用して ID プロバイダーを統合する
<a name="authentication-api-gateway"></a>

このトピックでは、 AWS Lambda 関数を使用して API Gateway メソッドをバックアップする方法について説明します。ID プロバイダーを統合するために RESTful API が必要な場合、または AWS WAF を使用してその機能をジオブロッキングまたはレート制限リクエストに活用する場合は、このオプションを使用します。

ほとんどのユースケースでは、カスタム ID プロバイダーを設定する推奨方法は、 を使用することです[カスタム ID プロバイダーソリューション](custom-idp-toolkit.md)。

「**API ゲートウェイを使用して ID プロバイダを統合する場合の制限事項**」
+ この構成はカスタムドメインをサポートしていません。
+ この構成は、プライベート API Gateway URL をサポートしていません。

これらのいずれかが必要な場合は、API Gateway なしで Lambda を ID プロバイダーとして使用できます。詳細については、「[AWS Lambda を使用して ID プロバイダーを統合する](custom-lambda-idp.md)」を参照してください。

## API Gateway メソッドを使用した認証
<a name="authentication-custom-ip"></a>

Transfer Family の ID プロバイダーとして使用する API Gateway メソッドを作成できます。このアプローチは、API を作成して提供するための非常に安全な方法です。API Gateway を使用すると、HTTPS エンドポイントを作成して、すべての受信 API オペレーションをセキュリティを強化して送信できます。API Gateway サービスの詳細については、[API Gateway デベロッパーガイド](https://docs.aws.amazon.com/apigateway/latest/developerguide/welcome.html)を参照してください。

API Gateway は、 という名前の認可方法を提供します。これにより`AWS_IAM`、 が内部 AWS で使用する AWS Identity and Access Management (IAM) に基づく認証と同じ認証が提供されます。`AWS_IAM` で認証を有効にした場合、API を呼び出す明示的なアクセス権限を持つ呼び出し側のみがその API Gateway メソッドに到達できます。

API Gateway メソッドをTransfer Family カスタム ID プロバイダーとして使用するには、API Gateway メソッドの IAM を有効にします。このプロセスの一環として、Transfer Family についてゲートウェイを使用するためのアクセス許可を持つ IAM ロールを提供します。

**注記**  
セキュリティを強化するために、ウェブアプリケーションのファイアウォールを設定できます。 AWS WAF はウェブアプリケーションファイアウォールで、これにより Amazon API Gateway に転送される HTTP および HTTPS リクエストのモニタリングが可能です。詳細については、「[ウェブアプリケーションファイアウォールを追加する](web-application-firewall.md)」を参照してください

**API Gateway キャッシュを有効にしない**  
Transfer Family のカスタム ID プロバイダーとして使用する場合、API Gateway メソッドのキャッシュを有効にしないでください。次の理由により、キャッシュは認証リクエストに対して不適切で無効です。  
各認証リクエストは一意であり、キャッシュされたレスポンスではなく、ライブレスポンスが必要です
Transfer Family は API Gateway に重複または繰り返しリクエストを送信しないため、キャッシュには利点はありません。
キャッシュを有効にすると、API Gateway が不一致データで応答し、認証リクエストへの無効な応答が発生します。

**Transfer Family でカスタム認証に API Gateway メソッドを使用するには**

1.  CloudFormation スタックを作成します。これを実行するには:
**注記**  
スタックテンプレートが更新され、BASE64-encodedパスワードが使用されました。詳細については、「」を参照してください[CloudFormation テンプレートの改善](#base64-templates)。

   1. [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) で CloudFormation コンソールを開きます。

   1. 「 *AWS CloudFormation ユーザーガイド*」の CloudFormation 「スタックテンプレート[の選択」の「既存のテンプレートからスタックを](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-using-console-create-stack-template.html)デプロイする手順」に従います。

   1. 次の基本テンプレートのいずれかを使用して、Transfer Family でカスタム ID プロバイダーとして使用する AWS Lambda Backed API Gateway メソッドを作成します。
      + [基本スタックテンプレート](https://s3.amazonaws.com/aws-transfer-resources/custom-idp-templates/aws-transfer-custom-idp-basic-apig.template.yml)

        デフォルトでは、API Gateway メソッドは、ハードコードされた SSH (Secure Shell) キーまたはパスワードを使用して単一のサーバーで単一のユーザーを認証するカスタム ID プロバイダーとして使用されます。デプロイ後に Lambda 関数コードを変更すれば異なる処理を実行できます。
      + [AWS Secrets Manager スタックテンプレート](https://s3.amazonaws.com/aws-transfer-resources/custom-idp-templates/aws-transfer-custom-idp-secrets-manager-apig.template.yml)

        デフォルトでは、API Gateway メソッドは、Secrets Manager 内の `aws/transfer/server-id/username` 形式のエントリに対して認証します。さらに、シークレットは、Transfer Family に返されるすべてのユーザープロパティのキーバリューペアを保持する必要があります。デプロイ後に Lambda 関数コードを変更すれば異なる処理を実行できます。詳細については、ブログ記事[「 AWS Transfer Family を使用したパスワード認証の有効化 AWS Secrets Manager](https://aws.amazon.com/blogs/storage/enable-password-authentication-for-aws-transfer-family-using-aws-secrets-manager-updated/)」を参照してください。
      + [Okta スタックテンプレート](https://s3.amazonaws.com/aws-transfer-resources/custom-idp-templates/aws-transfer-custom-idp-okta-apig.template.yml)

        API Gateway メソッドは、Transfer Family のカスタム ID プロバイダーとして Okta と統合されます。詳細については、ブログ記事「[AWS Transfer Familyで Okta を ID プロバイダーとして使う](https://aws.amazon.com/blogs/storage/using-okta-as-an-identity-provider-with-aws-transfer-for-sftp/)」を参照してください。

   これらのスタックのいずれかをデプロイすることが、カスタム ID プロバイダーをTransfer Family ワークフローに統合するうえで最も簡単な方法です。各スタックは Lambda 関数を使用して、API Gateway に基づく API メソッドをサポートします。その後、Transfer Family でカスタム ID プロバイダーとして API メソッドを使用できます。デフォルトでは、Lambda 関数は、`myuser` という単一のユーザーを `MySuperSecretPassword` のパスワードで認証します。デプロイ後に、これらの認証情報を編集するか Lambda 関数コードを更新すれば異なる処理を実行できます。
**重要**  
デフォルトのユーザーとパスワード認証情報を編集することをお勧めします。

   スタックのデプロイ後には、CloudFormation コンソールの [**Output**] (出力) にタブにスタックについての詳細が表示されます。具体的には、スタックの Amazon リソースネーム (ARN)、スタックが作成した IAM ロールの ARN、および新しいゲートウェイの URL が含まれます。
**注記**  
カスタム ID プロバイダーオプションを使用してユーザーのパスワードベースの認証を有効にし、API Gateway によって提供されるリクエストとレスポンスのログを有効にした場合、API Gateway はユーザーのパスワードを Amazon CloudWatch Logs に記録します。本稼働環境でこのログを使用することは推奨されません。詳細については、*API Gateway デベロッパーガイド*の「[API Gateway に CloudWatch API ログ記録を設定する](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-logging.html)」を参照してください。

1. サーバーの API Gateway メソッドの設定を確認します。これを実行するには:

   1. API Gateway コンソール ([https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway/)) を開きます。

   1.  CloudFormation テンプレートが生成した **Transfer Custom Identity Provider の基本テンプレート API** を選択します。ゲートウェイを表示するには、リージョンを選択する必要があります。

   1. **リソース**ペインで、**GET** を選択します。次の画面例は、正しいメソッド設定を示しています。  
![\[API 設定の詳細には、リクエストパスと URL クエリ文字列のメソッド設定パラメータが表示されます。\]](http://docs.aws.amazon.com/ja_jp/transfer/latest/userguide/images/apig-config-method-fields.png)

   この時点で、API Gateway をデプロイする準備が整いました。

1. [**Actions**] (アクション) で [**Deploy API**] (API のデプロイ) を選択します。[**Deplyment stage**] (デプロイステージ) で [**prod**] を選択してから [**Deploy**] (デプロイ) を選択します。

   API Gateway メソッドが正常にデプロイされたら、次のスクリーンショットに示すように、**ステージ** > **ステージの詳細**でそのパフォーマンスを表示します。
**注記**  
画面の最上部に表示される [**Invoke URL**] (呼び出し URL) アドレスをコピーします。次のステップで必要になる場合があります。  
![\[呼び出し URL が強調表示されたステージの詳細。\]](http://docs.aws.amazon.com/ja_jp/transfer/latest/userguide/images/apig-config-method-invoke.png)

1. [https://console.aws.amazon.com/transfer/](https://console.aws.amazon.com/transfer/) で AWS Transfer Family コンソールを開きます。

1. スタックの作成時に Transfer Family が作成されたはずです。そうでない場合は、以下の手順を使用してサーバーを設定します。

   1. [**Create server**] (サーバーの作成) を選択すると [**Create server**] (サーバーの作成) ページが開きます。[**Choose an identity provider**] (ID プロバイダーの選択) で [**Custom**] (カスタム) を選択してから、[**Use Amazon API Gateway to connect to your identity provider**] (Amazon API Gateway を使用してアイデンティティプロバイダーに接続する) を選択します (次の画面例を参照)。  
![\[カスタム ID プロバイダーが選択され、ID プロバイダーへの接続用に API Gateway が選択された ID プロバイダー画面。\]](http://docs.aws.amazon.com/ja_jp/transfer/latest/userguide/images/create-server-choose-idp-custom.png)

   1. [**Provide an Amazon API Gateway URL**] (Amazon API Gateway URL を指定) テキストボックスに、ステップ 3 で作成した API Gateway エンドポイントの [**Invoke URL**] (呼び出し URL) アドレスを貼り付けます。

   1. **ロール** で、 CloudFormation テンプレートによって作成された IAM ロールを選択します。このロールにより、Transfer Family が API Gateway メソッドを呼び出せるようになります。

      呼び出しロールには、ステップ 1 で作成した CloudFormation スタック用に選択したスタック名が含まれます。次のような形式です: `CloudFormation-stack-name-TransferIdentityProviderRole-ABC123DEF456GHI`

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

## API Gateway メソッドを実装する
<a name="authentication-api-method"></a>

Transfer Family のカスタム ID プロバイダーを作成するには、API Gateway メソッドで`/servers/serverId/users/username/config` のリソースパスを持つ単一のメソッドを実装する必要があります。`serverId` と `username` の値は RESTful リソースパスから取得されます。また、下図のように、`sourceIp`と`protocol`を「**URL クエリ文字列パラメータ**」として「**メソッドリクエスト**」に追加します。

![\[GET メソッドの詳細を示す API Gateway のリソース画面。\]](http://docs.aws.amazon.com/ja_jp/transfer/latest/userguide/images/apig-config-method-request.png)


**注記**  
ユーザー名は、最小 3 文字、最大 100 文字にする必要があります。ユーザー名には、a～z、A～Z、0～9、アンダースコア「\$1」、ハイフン「-」、ピリオド「.」、アットマーク「@」を使用できます。ユーザー名は、ハイフン '-'、ピリオド '.'、またはアットマーク '@' で始めることはできません。

Transfer Family がユーザーに代わってパスワード認証を試みると、サービスが `Password:` ヘッダーフィールドを提供します。`Password:` ヘッダーが存在しない場合、Transfer Family はパブリックキー認証でユーザーを認証しようと試みます。

エンドユーザーの認証と認可に ID プロバイダーを使用する場合、エンドユーザーが使用するクライアントの IP アドレスに基づいてアクセスリクエストを許可または拒否できます。この機能を使用すると、S3 バケットまたは Amazon EFS ファイルシステムに保存されたデータに、信頼済みとして指定した IP アドレスからのみ、サポートされているプロトコル経由でアクセスできるようになります。この機能を有効にするには、`sourceIp`をクエリ文字列に含める必要があります。

サーバーで複数のプロトコルを有効にしており、複数のプロトコルで同じユーザー名を使用してアクセスを提供したい場合、各プロトコルに固有の認証情報が ID プロバイダーに設定されている限り、そうすることができます。この機能を有効にするには、RESTful リソースパスに `protocol` 値を含める必要があります。

API Gateway メソッドは常に HTTP ステータスコード `200` を返す必要があります。その他の HTTP ステータスコードは、API へのアクセスエラーがあったことを示します。

**Amazon S3 のレスポンスの例**  
この例のレスポンス本文は、Amazon S3 では次の形式の JSON ドキュメントになります。

```
{
 "Role": "IAM role with configured S3 permissions",
 "PublicKeys": [
     "ssh-rsa public-key1",
     "ssh-rsa public-key2"
  ],
 "Policy": "STS Assume role session policy",
 "HomeDirectory": "/amzn-s3-demo-bucket/path/to/home/directory"
}
```

**注記**  
 ポリシーは、JSON で文字列としてエスケープされます。例:   

****  

```
"Policy":
"{
  \"Version\": \"2012-10-17\",
  \"Statement\":
     [
     {\"Condition\":
        {\"StringLike\":
            {\"s3:prefix\":
               [\"user/*\", \"user/\"]}},
     \"Resource\": \"arn:aws:s3:::amzn-s3-demo-bucket\",
     \"Action\": \"s3:ListBucket\",
     \"Effect\": \"Allow\",
     \"Sid\": \"ListHomeDir\"},
     {\"Resource\": \"arn:aws:s3:::*\",
        \"Action\": [\"s3:PutObject\",
        \"s3:GetObject\",
        \"s3:DeleteObjectVersion\",
        \"s3:DeleteObject\",
        \"s3:GetObjectVersion\",
        \"s3:GetObjectACL\",
        \"s3:PutObjectACL\"],
     \"Effect\": \"Allow\",
     \"Sid\": \"HomeDirObjectAccess\"}]
}"
```

次のレスポンスの例は、論理ホームディレクトリタイプを有するユーザーを示しています。

```
{
   "Role": "arn:aws:iam::123456789012:role/transfer-access-role-s3",
   "HomeDirectoryType":"LOGICAL",
   "HomeDirectoryDetails":"[{\"Entry\":\"/\",\"Target\":\"/amzn-s3-demo-bucket1\"}]",
   "PublicKeys":[""]
}
```

**Amazon EFS のレスポンスの例**  
この例のレスポンス本文は、Amazon EFS では次の形式の JSON ドキュメントになります。

```
{
 "Role": "IAM role with configured EFS permissions",
 "PublicKeys": [
     "ssh-rsa public-key1",
     "ssh-rsa public-key2"
  ],
 "PosixProfile": {
   "Uid": "POSIX user ID",
   "Gid": "POSIX group ID",
   "SecondaryGids": [Optional list of secondary Group IDs],
 },
 "HomeDirectory": "/fs-id/path/to/home/directory"
}
```

`Role` フィールドは認証に成功したことを示します。パスワード認証を実行する場合 (`Password:` ヘッダーの提供時) には、SSH パブリックキーを提供する必要はありません。ユーザーが認証できない場合 (たとえば、パスワードが正しくない場合)、メソッドは `Role` を設定せずにレスポンスを返す必要があります。このようなレスポンスの例として、空の JSON オブジェクトがあります。

 次のレスポンスの例は、論理ホームディレクトリタイプを持つユーザーを示しています。

```
{
    "Role": "arn:aws:iam::123456789012:role/transfer-access-role-efs",
    "HomeDirectoryType": "LOGICAL",
    "HomeDirectoryDetails":"[{\"Entry\":\"/\",\"Target\":\"/faa1a123\"}]",
    "PublicKeys":[""],
    "PosixProfile":{"Uid":65534,"Gid":65534}
}
```

Lambda 関数にユーザーポリシーを JSON 形式で含めることができます。Transfer Family でのユーザーポリシーの設定の詳細については、「[アクセスコントロールの管理](users-policies.md)」を参照してください。

## デフォルトの Lambda 関数
<a name="authentication-lambda-examples-default"></a>

異なる認証戦略を実装するには、ゲートウェイで使用する Lambda 関数を編集します。アプリケーションのニーズを満たすために、Node.js 内で次の Lambda 関数の例を使用できます。Lambda の詳細については、[AWS Lambda デベロッパーガイド](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html)または「[Node.js による Lambda 関数の構築](https://docs.aws.amazon.com/lambda/latest/dg/lambda-nodejs.html)」を参照してください。

以下の Lambda 関数の例では、ユーザー名、パスワード（パスワード認証を行っている場合）、サーバー ID、プロトコル、クライアント IP アドレスを受け取っています。これらの入力を組み合わせて使用すると、ID プロバイダーを検索し、ログインを許可するかどうかを判断できます。

**注記**  
サーバーで複数のプロトコルを有効にしており、複数のプロトコルで同じユーザー名を使用してアクセスを提供したい場合、プロトコルに固有の認証情報が ID プロバイダーに設定されている限り、そうすることができます。  
File Transfer Protocol (FTP) については、Secure Shell (SSH) File Transfer Protocol (SFTP) and File Transfer Protocol over SSL (FTPS) とは異なる認証情報を維持することをお勧めします。SFTP や FTPS と異なり、FTP は認証情報を平文で送信します。FTP の認証情報を SFTP または FTPS から隔離することを推奨します。そうすれば、FTP の認証情報が共有または公開されても、SFTP または FTPS を使用しているワークロードは引き続き安全だからです。

この関数の例は、ロールと論理ホームディレクトリの詳細、ならびに (公開鍵認証を実行する場合には) パブリックキーを返します。

サービス管理対象ユーザーを作成するときは、そのユーザーのホームディレクトリを論理ディレクトリまたは物理ディレクトリに設定します。同様に、目的のユーザーに物理的または論理的なディレクトリ構造を伝えるには、Lambda 関数の結果が必要です。設定するパラメータは [[HomeDirectoryType]](https://docs.aws.amazon.com//transfer/latest/APIReference/API_CreateUser.html#TransferFamily-CreateUser-request-HomeDirectoryType) フィールドの値によって異なります。
+ `HomeDirectoryType`が`PATH`に設定される場合 — `HomeDirectory`フィールドはユーザーに表示される Amazon S3 バケットの絶対プレフィックスまたは Amazon EFS 絶対パスである必要があります。
+ `HomeDirectoryType`が`LOGICAL`に設定される場合 — `HomeDirectory`フィールドを設定「*しないで*」ください。代わりに、サービス管理対象ユーザー向けの [[HomeDirectoryDetails]](https://docs.aws.amazon.com//transfer/latest/APIReference/API_CreateUser.html#TransferFamily-CreateUser-request-HomeDirectoryMappings) パラメーターで説明されている値と同様に、必要なエントリ/ターゲットのマッピングを提供する`HomeDirectoryDetails`フィールドを設定します。

関数の例は[Lambda 関数の例](custom-lambda-idp.md#lambda-auth-examples)に記載されています。

## で使用する Lambda 関数 AWS Secrets Manager
<a name="authentication-lambda-examples-secrets-mgr"></a>

ID プロバイダー AWS Secrets Manager として を使用するには、サンプル CloudFormation テンプレートで Lambda 関数を使用できます。Lambda 関数は、認証情報を使用して Secrets Manager サービスにクエリを実行し、成功すると指定されたシークレットを返します。Secrets Manager の詳細については、[AWS Secrets Manager ユーザーガイド](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html)を参照してください。

この Lambda 関数を使用するサンプル CloudFormation テンプレートをダウンロードするには、 [が提供する Amazon S3 バケット AWS Transfer Family](https://s3.amazonaws.com/aws-transfer-resources/custom-idp-templates/aws-transfer-custom-idp-secrets-manager-apig.template.yml)に移動します。

## CloudFormation テンプレートの改善
<a name="base64-templates"></a>

API Gateway インターフェイスが公開されている CloudFormation テンプレートに改善されました。テンプレートは、API Gateway で BASE64-encodedされたパスワードを使用するようになりました。既存のデプロイは、この機能強化なしで引き続き機能しますが、基本的な US-ASCII 文字セット外の文字を含むパスワードは許可されません。

この機能を有効にするテンプレートの変更は次のとおりです。
+ `GetUserConfigRequest AWS::ApiGateway::Method` リソースにはこの`RequestTemplates`コードが必要です (斜体の行は更新された行です)

  ```
  RequestTemplates:
     application/json: |
     {
        "username": "$util.urlDecode($input.params('username'))",
        "password": "$util.escapeJavaScript($util.base64Decode($input.params('PasswordBase64'))).replaceAll("\\'","'")",
        "protocol": "$input.params('protocol')",
        "serverId": "$input.params('serverId')",
        "sourceIp": "$input.params('sourceIp')"
  }
  ```
+ `PasswordBase64` ヘッダーを使用するには、`GetUserConfig`リソース`RequestParameters`の を変更する必要があります (斜体の行は更新された行です）。

  ```
  RequestParameters:
     method.request.header.PasswordBase64: false
     method.request.querystring.protocol: false
     method.request.querystring.sourceIp: false
  ```

**スタックのテンプレートが最新かどうかを確認するには**

1. [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) で CloudFormation コンソールを開きます。

1. スタックのリストから、スタックを選択します。

1. 詳細パネルから、**テンプレート**タブを選択します。

1. 以下を探します。
   + を検索し`RequestTemplates`、次の行があることを確認します。

     ```
     "password": "$util.escapeJavaScript($util.base64Decode($input.params('PasswordBase64'))).replaceAll("\\'","'")",
     ```
   + を検索し`RequestParameters`、次の行があることを確認します。

     ```
     method.request.header.PasswordBase64: false
     ```

更新された行が表示されない場合は、スタックを編集します。 CloudFormation スタックを更新する方法の詳細については、「 *AWS CloudFormationユーザーガイド*[」の「スタックテンプレートの変更](https://docs.aws.amazon.com//AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-get-template.html)」を参照してください。

# 複数の認証方法の使用
<a name="custom-idp-mfa"></a>

Transfer Family サーバーは、複数の認証方法を使用するときに AND ロジックを制御します。Transfer Family は、これをカスタム ID プロバイダーへの 2 つの個別のリクエストとして扱います。ただし、その効果は結合されます。

認証を完了できるように、両方のリクエストは正しいレスポンスで正常に返される必要があります。Transfer Family では、2 つのレスポンスを完了する必要があります。つまり、必要なすべての要素 (Amazon EFS をストレージに使用する場合、ロール、ホームディレクトリ、ポリシー、POSIX プロファイル) が含まれます。Transfer Family では、パスワードレスポンスにパブリックキーを含めないようにする必要があります。

パブリックキーリクエストには、ID プロバイダーからの別のレスポンスが必要です。**パスワード、キー**、または**パスワードとキー**を使用する場合、その動作は変更されません。

SSH/SFTP プロトコルは、最初にパブリックキー認証を使用してソフトウェアクライアントにチャレンジし、次にパスワード認証をリクエストします。このオペレーションでは、ユーザーが認証を完了する前に、両方が成功することを義務付けています。

カスタム ID プロバイダーオプションでは、認証方法に次のいずれかのオプションを指定できます。
+ **パスワードまたはキー** – ユーザーはパスワードまたはキーを使用して認証できます。これは、デフォルト値です。
+ **パスワードのみ** – ユーザーは接続するためにパスワードを入力する必要があります。
+ **キーのみ** – ユーザーは接続するためにプライベートキーを指定する必要があります。
+ **パスワードとキー** – ユーザーは接続するためにプライベートキーとパスワードの両方を指定する必要があります。サーバーは最初にキーを確認し、キーが有効な場合はパスワードの入力を求めます。提供されたプライベートキーが保存されたパブリックキーと一致しない場合、認証は失敗します。

# カスタム ID プロバイダーの IPv6 サポート
<a name="custom-idp-ipv6"></a>

AWS Transfer Family カスタム ID プロバイダーは IPv6 接続を完全にサポートしています。カスタム ID プロバイダーを実装する場合、Lambda 関数は IPv4 クライアントと IPv6 クライアントの両方から認証リクエストを受信して処理できます。追加の設定は必要ありません。Lambda 関数は、リクエストの `sourceIp`フィールドでクライアントの IP アドレスを受け取ります。IPv4 アドレス ( など`203.0.113.42`) または IPv6 アドレス ( など) です`2001:db8:85a3:8d3:1319:8a2e:370:7348`。カスタム ID プロバイダーの実装では、両方のアドレス形式を適切に処理する必要があります。

**重要**  
カスタム ID プロバイダーが IP ベースの検証またはログ記録を実行する場合は、実装が IPv6 アドレス形式を適切に処理していることを確認します。IPv6 アドレスは IPv4 アドレスよりも長く、別の表記形式を使用します。

**注記**  
カスタム ID プロバイダーで IPv6 アドレスを処理するときは、単純な文字列比較ではなく、適切な IPv6 アドレス解析関数を使用していることを確認してください。IPv6 アドレスは、さまざまな正規形式 ( `fd00:b600::ec2`や など`fd00:b600:0:0:0:0:0:ec2`) で表現できます。実装言語で適切な IPv6 アドレスライブラリまたは関数を使用して、IPv6 アドレスを正しく検証して比較します。

**Example カスタム ID プロバイダーでの IPv4 アドレスと IPv6 アドレスの両方の処理**  

```
def lambda_handler(event, context):
    # Extract the source IP address from the request
    source_ip = event.get('sourceIp', '')
    
    # Log the client IP address (works for both IPv4 and IPv6)
    print(f"Authentication request from: {source_ip}")
    
    # Example of IP-based validation that works with both IPv4 and IPv6
    if is_ip_allowed(source_ip):
        # Continue with authentication
        # ...
    else:
        # Reject the authentication request
        return {
            "Role": "",
            "HomeDirectory": "",
            "Status": "DENIED"
        }
```

カスタム ID プロバイダーの実装の詳細については、「」を参照してください[AWS Lambda を使用して ID プロバイダーを統合する](custom-lambda-idp.md)。