マネージ コード (C#) を使用してファイルのアップロード時に電子メールを送信する FTP 認証プロバイダーを作成する方法

公開日: 2009 年 4 月 30 日 (作業者: robmcm (英語))

更新日: 2009 年 9 月 15 日 (作業者: robmcm (英語))

マイクロソフトでは、Windows Server® 2008 用に完全に書き換えた新しい FTP サービスを作成しました。この新しい FTP サービスでは多くの新機能が追加され、Web サイト作成者は簡単にコンテンツを発行でき、Web 管理者は多くのセキュリティ オプションと展開オプションを使用できます。

この新しい FTP 7.5 サービスでは、FTP サービスに付属の組み込み機能の拡張を可能にする拡張機能がサポートされます。具体的には、FTP 7.5 で、独自の認証プロバイダーおよび承認プロバイダーの作成がサポートされます。さらに、カスタム FTP ログ作成および FTP ユーザーのホーム ディレクトリ情報の判定を行うためのプロバイダーを作成することもできます。

FTP 7.5 拡張には、IIS 7 の HTTP プロセス モデルのような要求処理パイプラインはありませんが、IFtpLogProvider.Log() メソッドを使用して、FTP クライアントから送信された FTP コマンドに応答するカスタム アクションを実装でき、FTP 状態コードを検査して、FTP コマンドが成功したか失敗したかを判断できます(メモ: IFtpLogProvider.Log() メソッドをプロバイダーに実装した場合に、ログ ファイルに実際に書き込む必要はありません)。

このチュートリアルでは実例として、マネージ コードを使用して、単純な FTP プロバイダーを作成するステップを説明します。このプロバイダーでは、ファイルがアップロードされるたびに電子メールが送信され、アップロードが成功したか失敗したかに応じて電子メール メッセージのテキストが変更されます。

このチュートリアルの FTP プロバイダーは、IFtpLogProvider.Log() メソッドを実装し、FtpLogEntry.Command と FtpLogEntry.FtpStatus の値を使用して、クライアントからの FTP コマンドと FTP サービスからの応答状態を判断します。さらに、このプロバイダーは IFtpLogProvider.Initialize() メソッドをオーバーライドして、ApplicationHost.config 内のプロバイダー エントリにあるプロバイダー設定から、SMTP サーバー名とポート、および電子メール メッセージ用の電子メール アドレスを取得します。構成設定に SMTP 設定が追加されていない場合、FTP プロバイダーは FTP サービスに単純な例外を返し、何もしません。これらの例外は、ETW トレースで監視したり、デバッグ チャネルにこの状態を書き込むための Debug.WriteLine() ステートメントを追加することができます。

FTP クライアントは、ファイルを FTP サービスに送信するときに、STOR コマンドをサーバーに送信します。FTP サーバーは、このコマンドが成功したときには 226 状態、失敗したときには別の状態を返します。たとえば、ユーザーのディスク クォータを超えた場合は、FTP サービスは 550 状態を返します。

必要条件

この記事の手順を完了するには、以下の項目が必須です。

  1. Windows Server 2008 サーバーに IIS 7 がインストールされている必要があります。また、インターネット インフォメーション サービス (IIS) マネージャーもインストールされている必要があります。
  2. 新しい FTP 7.5 サービスがインストールされている必要があります。FTP 7.5 サービスは、Web サイト (https://www.iis.net/(英語)) からダウンロードしてインストールできます。次のいずれかのリンクを使用してください。
  3. Visual Studio 2008 を使用する必要があります(メモ: Visual Studio の旧バージョンを使用すると、このチュートリアルのステップの一部が不正確になる可能性があります)。

ステップ 1: プロジェクト環境のセットアップ

このステップでは、デモ プロバイダー用のプロジェクトを Visual Studio 2008 で作成します。

Microsoft Visual Studio 2008 を開きます。

[ファイル] メニューの [新規作成] をクリックし、[プロジェクト] をクリックします。

[新しいプロジェクト] ダイアログ ボックスで以下の操作を行います。

  • プロジェクトの種類として [Visual C#] を選択します。
  • テンプレートとして [クラス ライブラリ] を選択します。
  • プロジェクト名として「FtpMailDemo」と入力します。
  • [OK] をクリックします。

プロジェクトが開いたら、以下の操作を行って FTP 拡張機能ライブラリへの参照パスを追加します。

[プロジェクト] メニューの [FtpMailDemo のプロパティ] をクリックします。

[参照パス] タブをクリックします。

お使いの Windows バージョン用の FTP 拡張機能アセンブリへのパスを入力します。次は、オペレーティング システム ドライブが C: の場合です。

  • Windows Server 2008 および Windows Vista の場合:
    C:\Windows\assembly\GAC_MSIL\Microsoft.Web.FtpServer\7.5.0.0__31bf3856ad364e35
  • Windows 7 の場合:
    C:\Program Files\Reference Assemblies\Microsoft\IIS

[フォルダの追加] をクリックします。

厳密な名前のキーをプロジェクトに追加します。

  • [プロジェクト] メニューの [FtpMailDemo のプロパティ] をクリックします。
  • [署名] タブをクリックします。
  • [アセンブリの署名] チェック ボックスをオンにします。
  • 厳密なキー名を選択するドロップダウン ボックスから [<新規作成>] を選択します。
  • キー ファイルの名前として「FtpMailDemoKey」と入力します。
  • 必要な場合、キー ファイル用のパスワードを入力します。不要な場合は、[キー ファイルをパスワードで保護する] チェック ボックスをオフにします。
  • [OK] をクリックします。

オプション: カスタム ビルド イベントを追加して、開発用コンピューター上のグローバル アセンブリ キャッシュ (GAC) に DLL を自動的に追加できます。

  • [プロジェクト] メニューの [FtpMailDemo のプロパティ] をクリックします。

  • [ビルド イベント] タブをクリックします。

  • [ビルド後に実行するコマンド ライン] ダイアログ ボックスに、次を入力します。

    net stop ftpsvc
    call "%VS90COMNTOOLS%\vsvars32.bat">null
    gacutil.exe /if "$(TargetPath)"
    net start ftpsvc
    

プロジェクトを保存します。

ステップ 2: 拡張機能クラスの作成

このステップでは、デモ プロバイダー用の拡張機能インターフェイスを実装します。

  1. プロジェクトに FTP 拡張機能ライブラリへの参照を追加します。
    • [プロジェクト] メニューの [参照の追加] をクリックします。
    • [.NET] タブで、[Microsoft.Web.FtpServer] をクリックします。
    • [OK] をクリックします。
  2. プロジェクトに System.Web への参照を追加します。
    • [プロジェクト] メニューの [参照の追加] をクリックします。
    • [.NET] タブで、[System.Web] をクリックします。
    • [OK] をクリックします。
  3. 認証クラスのコードを追加します。
    • [ソリューション エクスプローラー] で [Class1.cs] ファイルをダブルクリックします。

    • 既存のコードを削除します。

    • エディターに次のコードを貼り付けます。

      using System;
      using System.Collections.Specialized;
      using System.Diagnostics;
      using System.Net.Mail;
      using System.Text;
      using Microsoft.Web.FtpServer;
      publicsealedclass FtpMailDemo : BaseProvider, IFtpLogProvider
      {
      privatestring smtpServerName;
      privatestring smtpFromAddress;
      privatestring smtpToAddress;
      privateint smtpServerPort;
      // 既定の初期化メソッドをオーバーライドします。protectedoverridevoid Initialize(StringDictionary config)
      {
      // 構成からプロバイダー設定を取得します。
      smtpServerName = config["smtpServerName"];
      smtpFromAddress = config["smtpFromAddress"];
      smtpToAddress = config["smtpToAddress"];
      // 構成した設定の間違いを検出して処理します。if (!int.TryParse(config["smtpServerPort"], out smtpServerPort))
      {
      smtpServerPort = 25;
      }
      if (string.IsNullOrEmpty(smtpServerName))
      {
      thrownew ArgumentException(
      "構成内に smtpServerName 値がありません。");
      }
      if (string.IsNullOrEmpty(smtpFromAddress))
      {
      thrownew ArgumentException(
      "構成内に smtpFromAddress 値がありません。");
      }
      if (string.IsNullOrEmpty(smtpToAddress))
      {
      thrownew ArgumentException(
      "構成内に smtpToAddress 値がありません。");
      }
      }
      // ログ メソッドを実装します。void IFtpLogProvider.Log(FtpLogEntry loggingParameters)
      {
      // ファイルのアップロード操作のテストです。if (loggingParameters.Command == "STOR")
      {
      // SMTP メッセージを作成します。
      SmtpClient smtpClient =
      new SmtpClient(smtpServerName, smtpServerPort);
      MailAddress mailFromAddress =
      new MailAddress(smtpFromAddress);
      MailAddress mailToAddress = new
      MailAddress(smtpToAddress);
      using (MailMessage mailMessage =
      new MailMessage(mailFromAddress, mailToAddress))
      {
      // SMTP メッセージを UTF8 として処理します。
      mailMessage.BodyEncoding = Encoding.UTF8;
      // 操作の成功のテストです。if (loggingParameters.FtpStatus == 226)
      {
      // 成功した操作用にカスタマイズしたメッセージを作成します。
      mailMessage.Subject = "ファイルのアップロード成功";
      mailMessage.Body = loggingParameters.UserName +
      " は、次の場所へのファイルのアップロードに成功しました: " +
      loggingParameters.FullPath;
      }
      else
      {
      // 失敗した操作用にカスタマイズしたメッセージを作成します。
      mailMessage.Subject = "ファイル操作状態";
      mailMessage.Body =
      "FTP サービスから " +
      loggingParameters.FtpStatus + " の状態が返されました。" +
      loggingParameters.FtpSubStatus +
      " は、" + loggingParameters.UserName +
      " がファイルを次の場所にアップロードしようとしたときの副状態です: " +
      loggingParameters.FullPath;
      }
      try
      {
      // 電子メール メッセージを送信します。
      smtpClient.Send(mailMessage);
      }
      catch (SmtpException ex)
      {
      // 電子メールの送信に失敗した場合に、例外メッセージを// デバッグ チャネルに送信します。
      Debug.WriteLine(ex.Message.ToString());
      }
      }
      }
      }
      }
      
  4. プロジェクトを保存してビルドします。

メモ: GAC にアセンブリを登録するオプションのステップを使用しなかった場合は、アセンブリを IIS 7 が実行されているコンピューターに手動でコピーし、Gacutil.exe ツールを使用して GAC にアセンブリを追加する必要があります。詳細については、マイクロソフトの MSDN Web サイトの次のトピックを参照してください。

グローバル アセンブリ キャッシュ ツール (Gacutil.exe)

ステップ 3: FTP へのカスタム プロバイダーの追加

このステップでは、デモ プロバイダーを FTP サービスおよび FTP サイトに追加します。

  1. 拡張機能プロバイダー用のアセンブリ情報を判断します。
    • Windows Explorer で、パス C:\Windows\assembly を開きます。ここで、C: はオペレーティング システム ドライブです。
    • FtpMailDemo アセンブリを探します。
    • アセンブリを右クリックし、[プロパティ] をクリックします。
    • [カルチャ] の値 ([Neutral] など) をコピーします。
    • [バージョン] 番号 ([1.0.0.0] など) をコピーします。
    • [公開キー トークン] の値 ([426f62526f636b73] など) をコピーします。
    • [キャンセル] をクリックします。
  2. FTP プロバイダーのグローバル リストに拡張機能プロバイダーを追加します。
    • この時点では、カスタム プロバイダーに関連する構成設定を行って IIS に追加するための UI がないので、次のようなコマンド ライン構文を使用する必要があります。

      appcmd.exe set config -section:system.ftpServer/providerDefinitions /+"[name='FtpMailDemo',type='FtpMailDemo,FtpMailDemo,version=1.0.0.0,Culture=neutral,PublicKeyToken=426f62526f636b73']" /commit:apphost
      appcmd.exe set config -section:system.ftpServer/providerDefinitions /+"activation.[name='FtpMailDemo']" /commit:apphost
      appcmd.exe set config -section:system.ftpServer/providerDefinitions /+"activation.[name='FtpMailDemo'].[key='smtpServerName',value='localhost']" /commit:apphost
      appcmd.exe set config -section:system.ftpServer/providerDefinitions /+"activation.[name='FtpMailDemo'].[key='smtpServerPort',value='25']" /commit:apphost
      appcmd.exe set config -section:system.ftpServer/providerDefinitions /+"activation.[name='FtpMailDemo'].[key='smtpFromAddress',value='someone@contoso.com']" /commit:apphost
      appcmd.exe set config -section:system.ftpServer/providerDefinitions /+"activation.[name='FtpMailDemo'].[key='smtpToAddress',value='someone@contoso.com']" /commit:apphost
      

      メモ: プロバイダーのマネージ型情報および SMTP サーバーと電子メール アドレスの構成設定を使用して、上記の構文を更新する必要があります。

  3. サイトにカスタム プロバイダーを追加します。
    • この時点では、サイトにカスタム機能を追加するための UI がないので、Default Web Site を構成する次の例のようなコマンド ライン構文を使用する必要があります。
      AppCmd set site "Default Web Site" /+ftpServer.customFeatures.providers.[name='FtpMailDemo',enabled='true'] /commit:apphost

まとめ

このチュートリアルでは、次について学びました。

  • カスタム FTP プロバイダー用に Visual Studio 2008 でプロジェクトを作成する方法
  • カスタム FTP 機能用の拡張機能インターフェイスの実装方法
  • FTP サービスへのカスタム プロバイダーの追加方法

ユーザーが FTP サイトへのファイルのアップロードを試みたときに、FTP サービスは、プロバイダー定義に指定されている SMTP サーバー設定を使用して、成功または失敗の電子メール メッセージを送信します。

関連コンテンツ

記事