次の方法で共有


SQL Server でのメンバーシップ スキーマの作成 (C#)

作成者: Scott Mitchell

手記

この記事が作成されて以来、ASP.NET メンバーシップ プロバイダーは ASP.NET Identityに置き換えられました。 この記事の執筆時点で紹介したメンバーシップ プロバイダーではなく、ASP.NET ID プラットフォームを使用するようにアプリを更新することを強くお勧めします。 ASP.NET ID には、ASP.NET メンバーシップ システムに比して、次のような多くの利点があります。

  • パフォーマンスの向上
  • 拡張性とテスト容易性の向上
  • OAuth、OpenID Connect、および 2 要素認証のサポート
  • クレーム ベースのアイデンティティ サポート
  • ASP.Net Core との相互運用性の向上

コードのダウンロードまたはPDF のダウンロード

このチュートリアルでは、まず、SqlMembershipProvider を使用するために必要なスキーマをデータベースに追加する方法を調べることから始めます。 その後、スキーマのキー テーブルを調べて、その目的と重要性について説明します。 このチュートリアルでは、メンバーシップ フレームワークで使用する必要があるプロバイダー ASP.NET アプリケーションに指示する方法について説明します。

紹介

前の 2 つのチュートリアルでは、フォーム認証を使用して Web サイトの訪問者を識別しました。 フォーム認証フレームワークを使用すると、開発者は簡単にユーザーを Web サイトにログインさせ、認証チケットを使用してページ アクセス間でユーザーを覚えやすくなります。 FormsAuthentication クラスには、チケットを生成して訪問者の Cookie に追加するためのメソッドが含まれています。 FormsAuthenticationModule は、すべての受信要求を調べ、有効な認証チケットを持つ要求に対して、GenericPrincipalFormsIdentity オブジェクトを作成し、現在の要求に関連付けます。 フォーム認証は、ログイン時に訪問者に認証チケットを付与し、それ以降の要求ではそのチケットを解析してユーザーの ID を判断するためのメカニズムにすぎません。 Web アプリケーションでユーザー アカウントをサポートするには、引き続きユーザー ストアを実装し、資格情報の検証、新しいユーザーの登録、およびその他のユーザー アカウント関連タスクの無数の機能を追加する必要があります。

ASP.NET 2.0 より前のバージョンでは、開発者は、これらのユーザー アカウント関連のすべてのタスクを実装する必要がありました。 幸いなことに、ASP.NET チームはこの欠点を認識し、ASP.NET 2.0 でメンバーシップ フレームワークを導入しました。 メンバーシップ フレームワークは、コア ユーザー アカウント関連のタスクを実行するためのプログラムによるインターフェイスを提供する、.NET Framework のクラスのセットです。 このフレームワークは、プロバイダー モデルの上に構築されています。これにより、開発者はカスタマイズされた実装を標準化された API にプラグインできます。

セキュリティの基本と ASP.NET サポート チュートリアルで説明したように、.NET Framework には、ActiveDirectoryMembershipProviderSqlMembershipProviderの 2 つの組み込みメンバーシップ プロバイダーが付属しています。 その名前が示すように、SqlMembershipProvider はユーザー ストアとして Microsoft SQL Server データベースを使用します。 アプリケーションでこのプロバイダーを使用するには、ストアとして使用するデータベースをプロバイダーに伝える必要があります。 ご想像のとおり、SqlMembershipProvider は、ユーザー ストア データベースに特定のデータベース テーブル、ビュー、ストアド プロシージャがあることを想定しています。 この予想されるスキーマを選択したデータベースに追加する必要があります。

このチュートリアルでは、まず、SqlMembershipProviderを使用するために必要なスキーマをデータベースに追加する手法を調べることから始めます。 その後、スキーマのキー テーブルを調べて、その目的と重要性について説明します。 このチュートリアルでは、メンバーシップ フレームワークで使用する必要があるプロバイダー ASP.NET アプリケーションに指示する方法について説明します。

それでは始めましょう。

手順 1: ユーザー ストアを配置する場所を決定する

ASP.NET アプリケーションのデータは、通常、データベース内の多数のテーブルに格納されます。 SqlMembershipProvider データベース スキーマを実装する場合、メンバーシップ スキーマをアプリケーション データと同じデータベースに配置するか、代替データベースに配置するかを決定する必要があります。

次の理由から、アプリケーション データと同じデータベースにメンバーシップ スキーマを見つけることをお勧めします。

  • 保守容易性 1 つのデータベースにデータがカプセル化されているアプリケーションは、2 つの別個のデータベースを持つアプリケーションよりも理解、保守、デプロイが容易です。
  • リレーショナル整合性' は、アプリケーション テーブルと同じデータベース内にメンバーシップ関連テーブルを見つけることで、メンバーシップ関連テーブルと関連アプリケーション テーブルの主キーの間に 外部キー制約 確立できます。

ユーザー ストアとアプリケーション データを個別のデータベースに分離するのは、それぞれが個別のデータベースを使用する複数のアプリケーションがあるが、共通のユーザー ストアを共有する必要がある場合にのみ有効です。

データベースの作成

2 番目のチュートリアル以降に構築しているアプリケーションには、まだデータベースが必要ありません。 今すぐユーザー ストアのために一つが必要です。 1 つ作成し、SqlMembershipProvider プロバイダーに必要なスキーマを追加します (手順 2 を参照)。

手記

このチュートリアル シリーズでは、Microsoft SQL Server 2005 Express Edition データベース を使用して、アプリケーション テーブルと スキーマを格納します。 この決定は、次の 2 つの理由で行われました。最初に、コストが原因で無料です。Express Edition は SQL Server 2005 の最も読みやすくアクセス可能なバージョンです。次に、SQL Server 2005 Express Edition データベースを Web アプリケーションの App_Data フォルダーに直接配置できるため、データベースと Web アプリケーションを 1 つの ZIP ファイルにまとめてパッケージ化し、特別なセットアップ手順や構成オプションなしで再デプロイすることができます。 Express Edition 以外のバージョンの SQL Server を使用しながら進めてもかまいません。 手順は実質的に同じです。 SqlMembershipProvider スキーマは、Microsoft SQL Server 2000 以降の任意のバージョンで動作します。

ソリューション エクスプローラーで、App_Data フォルダーを右クリックし、[新しい項目の追加] を選択します。 (プロジェクトに App_Data フォルダーが表示されない場合は、ソリューション エクスプローラーでプロジェクトを右クリックし、[ASP.NET フォルダーの追加] を選択し、App_Data選択します)。[新しい項目の追加] ダイアログ ボックスで、SecurityTutorials.mdfという名前の新しい SQL Database を追加することを選択します。 このチュートリアルでは、SqlMembershipProvider スキーマをこのデータベースに追加します。以降のチュートリアルでは、アプリケーション データをキャプチャするための追加のテーブルを作成します。

App_Data フォルダー に SecurityTutorials.mdf Database という名前の新しい SQL データベースを追加する

図 1: App_Data フォルダーに SecurityTutorials.mdf Database という名前の新しい SQL Database を追加します (フルサイズの画像を表示するをクリックします)

App_Data フォルダーにデータベースを追加すると、データベース エクスプローラー ビューにデータベースが自動的に含まれます。 (非 Express Edition バージョンの Visual Studio では、データベース エクスプローラーはサーバー エクスプローラーと呼ばれます)。データベース エクスプローラーに移動し、追加した SecurityTutorials データベースを展開します。 [データベース エクスプローラー] 画面が表示されない場合は、[表示] メニューの [データベース エクスプローラー] を選択するか、Ctrl + Alt + S キーを押します。 図 2 に示すように、SecurityTutorials データベースは空です。テーブルもビューもストアド プロシージャも含んでいません。

現在、SecurityTutorialsのデータベースは空です

図 2: SecurityTutorials データベースは現在空です (フルサイズの画像を表示するをクリックします)

手順 2:SqlMembershipProviderスキーマをデータベースに追加する

SqlMembershipProvider では、テーブル、ビュー、およびストアド プロシージャの特定のセットをユーザー ストア データベースにインストールする必要があります。 これらの必要なデータベース オブジェクトは、aspnet_regsql.exe ツールを使用して追加できます。 このファイルは、%WINDIR%\Microsoft.Net\Framework\v2.0.50727\ フォルダーにあります。

手記

aspnet_regsql.exe ツールには、コマンド ライン機能とグラフィカル ユーザー インターフェイスの両方が用意されています。 グラフィカルインターフェイスは、よりユーザーフレンドリーであり、我々はこのチュートリアルで調べるものです。 コマンド ライン インターフェイスは、ビルド スクリプトや自動テスト シナリオなど、SqlMembershipProvider スキーマの追加を自動化する必要がある場合に便利です。

aspnet_regsql.exe ツールは、指定した SQL Server データベース ASP.NET アプリケーション サービス を追加または削除するために使用されます。 ASP.NET アプリケーション サービスには、SqlMembershipProviderSqlRoleProviderのスキーマと、他の ASP.NET 2.0 フレームワーク用の SQL ベースのプロバイダーのスキーマが含まれます。 aspnet_regsql.exe ツールに 2 ビットの情報を提供する必要があります。

  • アプリケーション サービスを追加または削除するかどうか、および
  • アプリケーション サービス スキーマの追加または削除元のデータベース

データベースの使用を求めるプロンプトで、aspnet_regsql.exe ツールは、データベースが存在するサーバーの名前、データベースに接続するためのセキュリティ資格情報、およびデータベース名を指定するように求められます。 SQL Server の Express 以外のエディションを使用している場合、この情報は、ASP.NET Web ページを介してデータベースを操作するときに接続文字列を介して指定する必要があるのと同じ情報であるため、既にわかっている必要があります。 ただし、App_Data フォルダーで SQL Server 2005 Express Edition データベースを使用する場合のサーバー名とデータベース名の決定は、もう少し複雑です。

次のセクションでは、App_Data フォルダー内の SQL Server 2005 Express Edition データベースのサーバー名とデータベース名を簡単に指定する方法について説明します。 SQL Server 2005 Express Edition を使用していない場合は、「Application Services のインストール」セクションに進んでください。

App_Dataフォルダー内の SQL Server 2005 Express Edition データベースのサーバー名とデータベース名の決定

aspnet_regsql.exe ツールを使用するには、サーバー名とデータベース名を知る必要があります。 サーバー名は localhost\InstanceName。 ほとんどの場合、InstanceNameSQLExpressです。 ただし、SQL Server 2005 Express Edition を手動でインストールした場合 (つまり、Visual Studio のインストール中に自動的にインストールしなかった場合)、別のインスタンス名を選択した可能性があります。

データベース名は少し複雑です。 通常、App_Data フォルダー内のデータベースには、データベース ファイルへのパスと共に グローバル一意識別子 を含むデータベース名があります。 aspnet_regsql.exeを使用してアプリケーション サービス スキーマを追加するには、このデータベース名を決定する必要があります。

データベース名を確認する最も簡単な方法は、SQL Server Management Studio を使用してデータベース名を調べることです。 SQL Server Management Studio には、SQL Server 2005 データベースを管理するためのグラフィカル インターフェイスが用意されていますが、SQL Server 2005 の Express Edition には付属していません。 良いニュースは、SQL Server Management Studio の無料の Express Edition をダウンロードできることです。

手記

デスクトップに非 Express Edition バージョンの SQL Server 2005 もインストールされている場合は、Management Studio のフル バージョンがインストールされている可能性があります。 完全なバージョンを使用して、Express Edition の以下で説明するのと同じ手順に従って、データベース名を決定できます。

まず、Visual Studio を閉じて、データベース ファイルに対して Visual Studio によって課されたロックが閉じられるようにします。 次に、SQL Server Management Studio を起動し、SQL Server 2005 Express Edition の localhost\InstanceName データベースに接続します。 前述のように、インスタンス名が SQLExpressされる可能性があります。 [認証] オプションで、[Windows 認証] を選択します。

SQL Server 2005 Express Edition インスタンスへの接続

図 3: SQL Server 2005 Express Edition インスタンスに接続します (フルサイズの画像を表示するにはクリックします)

SQL Server 2005 Express Edition インスタンスに接続すると、Management Studio にはデータベース、セキュリティ設定、サーバー オブジェクトなどのフォルダーが表示されます。 [データベース] タブを展開すると、 データベースがデータベース インスタンスに登録 されていないことがわかります。最初にデータベースをアタッチする必要があります。

[データベース] フォルダーを右クリックし、コンテキスト メニューから [アタッチ] を選択します。 [データベースのアタッチ] ダイアログ ボックスが表示されます。 ここから[追加]ボタンをクリックし、SecurityTutorials.mdf データベースを参照して、[OK]をクリックします。 図 4 は、SecurityTutorials.mdf データベースが選択された後の [データベースのアタッチ] ダイアログ ボックスを示しています。 図 5 は、データベースが正常にアタッチされた後の Management Studio のオブジェクト エクスプローラーを示しています。

SecurityTutorials.mdf データベース をアタッチする

図 4: SecurityTutorials.mdf データベースをアタッチする (フルサイズの画像を表示する] をクリックします)

データベース フォルダーにSecurityTutorials.mdf データベースが表示

図 5: データベース フォルダーに SecurityTutorials.mdf データベースが表示されます (フルサイズの画像を表示するにはクリック)

図 5 に示すように、SecurityTutorials.mdf データベースの名前はかなり控えめです。 覚えやすい (入力しやすい) 名前に変更しましょう。 データベースを右クリックし、コンテキスト メニューから [名前の変更] を選択し、SecurityTutorialsDatabase名前を変更します。 これにより、ファイル名は変更されず、データベースが SQL Server を識別するために使用する名前だけが変更されます。

データベースの名前を SecurityTutorialsDatabase に変更する

図 6: データベースの名前を SecurityTutorialsDatabaseに変更します (フルサイズの画像を表示するをクリックします)

この時点で、SecurityTutorials.mdf データベース ファイルのサーバー名とデータベース名 (それぞれ localhost\InstanceNameSecurityTutorialsDatabase) がわかっています。 これで、aspnet_regsql.exe ツールを使用してアプリケーション サービスをインストールする準備ができました。

Application Services のインストール

aspnet_regsql.exe ツールを起動するには、スタート メニューに移動し、[実行] を選択します。 テキスト ボックスに「%WINDIR%\Microsoft.Net\Framework\v2.0.50727\aspnet_regsql.exe」と入力し、[OK] をクリックします。 または、Windows エクスプローラーを使用して適切なフォルダーにドリルダウンし、aspnet_regsql.exe ファイルをダブルクリックすることもできます。 どちらの方法でも同じ結果が得られます。

コマンド ライン引数を指定せずに aspnet_regsql.exe ツールを実行すると、ASP.NET SQL Server セットアップ ウィザードのグラフィカル ユーザー インターフェイスが起動します。 ウィザードを使用すると、指定したデータベース上の ASP.NET アプリケーション サービスを簡単に追加または削除できます。 図 7 に示すウィザードの最初の画面では、ツールの目的について説明します。

ASP.NET SQL Server セットアップ ウィザードを使用してメンバーシップ スキーマ を追加する

図 7: ASP.NET SQL Server セットアップ ウィザードを使用してメンバーシップ スキーマを追加する (クリックすると、フルサイズのイメージが表示されます)

ウィザードの 2 番目の手順では、アプリケーション サービスを追加するか削除するかを確認します。 SqlMembershipProviderに必要なテーブル、ビュー、ストアド プロシージャを追加する場合は、[アプリケーション サービス用に SQL Server を構成する] オプションを選択します。 後でデータベースからこのスキーマを削除する場合は、このウィザードを再実行しますが、代わりに [既存のデータベースからアプリケーション サービス情報を削除する] オプションを選択します。

[Configure SQL Server for Application Services]\(アプリケーション サービス用に SQL Server を構成する\) オプション を選択します

図 8: [Configure SQL Server for Application Services]\(アプリケーション サービス用に SQL Server を構成する\) オプションを選択します (クリックすると、フルサイズのイメージが表示されます)

3 番目の手順では、データベース情報 (サーバー名、認証情報、データベース名) の入力を求められます。 このチュートリアルに従い、SecurityTutorials.mdf データベースを App_Dataに追加し、localhost\InstanceNameにアタッチし、名前を SecurityTutorialsDatabaseに変更した場合は、次の値を使用します。

  • サーバー: localhost\InstanceName
  • Windows 認証
  • データベース: SecurityTutorialsDatabase

データベース情報 を入力

図 9: データベース情報を入力します (フルサイズの画像を表示するをクリックします)

データベース情報を入力したら、[次へ] をクリックします。 最後の手順では、実行される手順の概要を示します。 [次へ] をクリックしてアプリケーション サービスをインストールし、[完了] をクリックしてウィザードを完了します。

手記

Management Studio を使用してデータベースをアタッチし、データベース ファイルの名前を変更した場合は、Visual Studio を再度開く前に、必ずデータベースをデタッチして Management Studio を閉じておきます。 SecurityTutorialsDatabase データベースをデタッチするには、データベース名を右クリックし、[タスク] メニューから [デタッチ] を選択します。

ウィザードが完了したら、Visual Studio に戻り、データベース エクスプローラーに移動します。 [テーブル] フォルダーを展開します。 プレフィックス aspnet_で始まる名前の一連のテーブルが表示されます。 同様に、さまざまなビューとストアド プロシージャは、[ビュー] フォルダーと [ストアド プロシージャ] フォルダーにあります。 これらのデータベース オブジェクトは、アプリケーション サービス スキーマを構成します。 手順 3 で、メンバーシップ固有およびロール固有のデータベース オブジェクトを確認します。

さまざまなテーブル、ビュー、ストアド プロシージャがデータベース に追加されました

図 10: さまざまなテーブル、ビュー、およびストアド プロシージャがデータベースに追加されました (クリックすると、フルサイズの画像が表示)

手記

aspnet_regsql.exe ツールのグラフィカル ユーザー インターフェイスにより、アプリケーション サービス スキーマ全体がインストールされます。 ただし、コマンド ラインから aspnet_regsql.exe を実行する場合は、インストール (または削除) する特定のアプリケーション サービス コンポーネントを指定できます。 そのため、SqlMembershipProvider および SqlRoleProvider プロバイダーに必要なテーブル、ビュー、ストアド プロシージャのみを追加する場合は、コマンド ラインから aspnet_regsql.exe を実行します。 または、aspnet_regsql.exeで使用される T-SQL 作成スクリプトの適切なサブセットを手動で実行することもできます。 これらのスクリプトは、InstallCommon.sqlInstallMembership.sqlInstallRoles.sqlInstallProfile.sqlInstallSqlState.sqlなどの名前を持つ WINDIR%\Microsoft.Net\Framework\v2.0.50727\ フォルダーにあります。

この時点で、SqlMembershipProviderに必要なデータベース オブジェクトを作成しました。 ただし、メンバーシップ フレームワークに対して、SqlMembershipProvider (たとえば ActiveDirectoryMembershipProvider) を使用すること、および SqlMembershipProviderSecurityTutorials データベースを使用することを指示する必要があります。 使用するプロバイダーを指定する方法と、手順 4 で選択したプロバイダーの設定をカスタマイズする方法について説明します。 しかし、まず、先ほど作成したデータベース オブジェクトについて詳しく見てみましょう。

手順 3: スキーマのコア テーブルの概要

ASP.NET アプリケーションでメンバーシップフレームワークとロールフレームワークを操作する場合、実装の詳細はプロバイダーによってカプセル化されます。 今後のチュートリアルでは、.NET Framework の Membership および Roles クラスを使用して、これらのフレームワークとインターフェイスを作成します。 これらの高度な API を使用する場合、実行されるクエリや、SqlMembershipProviderSqlRoleProviderによって変更されるテーブルなど、低レベルの詳細に関心を持つ必要はありません。

この場合、手順 2 で作成したデータベース スキーマを調べなくても、メンバーシップとロールのフレームワークを自信を持って使用できます。 ただし、アプリケーション データを格納するテーブルを作成する場合は、ユーザーまたはロールに関連するエンティティの作成が必要になる場合があります。 これは、アプリケーション データ テーブルと手順 2 で作成したテーブルとの間に外部キー制約を確立する際に、SqlMembershipProvider スキーマと SqlRoleProvider スキーマに精通するのに役立ちます。 さらに、まれな状況では、(Membership クラスまたは Roles クラスではなく) データベース レベルでユーザーおよびロール ストアと直接インターフェイスする必要がある場合があります。

アプリケーションへのユーザー ストアのパーティション分割

メンバーシップとロールのフレームワークは、1 つのユーザーとロール ストアをさまざまなアプリケーション間で共有できるように設計されています。 Membership または Roles フレームワークを使用する ASP.NET アプリケーションでは、使用するアプリケーション パーティションを指定する必要があります。 つまり、複数の Web アプリケーションで同じユーザー ストアとロール ストアを使用できます。 図 11 は、HRSite、CustomerSite、SalesSite の 3 つのアプリケーションにパーティション分割されたユーザーストアとロール ストアを示しています。 これら 3 つの Web アプリケーションはそれぞれ独自の一意のユーザーとロールを持ちますが、すべて同じデータベース テーブルにユーザー アカウントとロール情報を物理的に格納します。

ユーザー アカウントは複数のアプリケーション間でパーティション分割されるかもしれません

図 11: 複数のアプリケーション間でユーザー アカウントがパーティション分割される可能性がある (フルサイズの画像を表示するをクリックします)

aspnet_Applications テーブルは、これらのパーティションを定義するものです。 データベースを使用してユーザー アカウント情報を格納する各アプリケーションは、このテーブルの行で表されます。 aspnet_Applications テーブルには、ApplicationIdApplicationNameLoweredApplicationName、および Descriptionの 4 つの列があります。 ApplicationIduniqueidentifier 型であり、テーブルの主キーです。ApplicationName は、アプリケーションごとに一意のわかりやすい名前を提供します。

その他のメンバーシップ関連テーブルとロール関連テーブルは、aspnet_ApplicationsApplicationId フィールドにリンクされます。 たとえば、各ユーザー アカウントのレコードを含む aspnet_Users テーブルには、ApplicationId 外部キー フィールドがあります。同様に、aspnet_Roles テーブルにも外部キー フィールドがあります。 これらのテーブルの ApplicationId フィールドは、ユーザー アカウントまたはロールが属するアプリケーション パーティションを指定します。

ユーザー アカウント情報の格納

ユーザー アカウント情報は、aspnet_Usersaspnet_Membershipの 2 つのテーブルに格納されます。 aspnet_Users テーブルには、重要なユーザー アカウント情報を保持するフィールドが含まれています。 最も関連する 3 つの列は次のとおりです。

  • UserId
  • UserName
  • ApplicationId

UserId は主キー (および型 uniqueidentifier) です。 UserNamenvarchar(256) の種類であり、パスワードと共にユーザーの資格情報を構成します。 (ユーザーのパスワードは、aspnet_Membership テーブルに格納されます)。ApplicationId は、ユーザー アカウントを aspnet_Applicationsの特定のアプリケーションにリンクします。 UserName 列と ApplicationId 列には複合 UNIQUE 制約 があります。 これにより、特定のアプリケーションで各 UserName が一意になりますが、異なるアプリケーションで同じ UserName を使用できるようになります。

aspnet_Membership テーブルには、ユーザーのパスワード、電子メール アドレス、最後のログイン日時などの追加のユーザー アカウント情報が含まれています。 aspnet_Users テーブルと aspnet_Membership テーブル内のレコードの間には、一対一の対応があります。 このリレーションシップは、テーブルの主キーとして機能する aspnet_MembershipUserId フィールドによって保証されます。 aspnet_Users テーブルと同様に、aspnet_Membership には、この情報を特定のアプリケーション パーティションに関連付ける ApplicationId フィールドが含まれています。

パスワードのセキュリティ保護

パスワード情報は、aspnet_Membership テーブルに格納されます。 SqlMembershipProvider では、次の 3 つの手法のいずれかを使用して、パスワードをデータベースに格納できます。

  • クリア - パスワードはプレーンテキストとしてデータベースに格納されます。 私はこのオプションを使用しないことを強くお勧めします。 データベースが侵害された場合 (バックドアを見つけたハッカーや、データベースにアクセスできる不満を持つ従業員など) は、すべてのユーザーの資格情報を取得できます。
  • ハッシュされた - パスワードは、一方向ハッシュ アルゴリズムとランダムに生成された salt 値を使用してハッシュされます。 このハッシュ値 (salt と共に) はデータベースに格納されます。
  • Encrypted - 暗号化されたバージョンのパスワードがデータベースに格納されます。

使用されるパスワード ストレージ手法は、Web.configで指定された SqlMembershipProvider 設定によって異なります。 手順 4 で SqlMembershipProvider 設定をカスタマイズする方法について説明します。 既定の動作では、パスワードのハッシュを格納します。

パスワードの格納を担当する列は、PasswordPasswordFormat、および PasswordSaltです。 PasswordFormat は、パスワードの格納に使用される手法を示す値を持つ int 型のフィールドです。Clear の場合は 0 です。ハッシュの場合は 1。Encrypted の場合は 2。 PasswordSalt は、使用されるパスワードストレージ手法に関係なく、ランダムに生成された文字列を割り当てられます。PasswordSalt の値は、パスワードのハッシュを計算するときにのみ使用されます。 最後に、Password 列には、プレーンテキスト パスワード、パスワードのハッシュ、暗号化されたパスワードなど、実際のパスワード データが含まれます。

表 1 は、パスワード MySecret を格納するときのさまざまなストレージ手法で、これら 3 つの列がどのようなものになるかを示しています。 .

ストレージ手法<_o3a_p /> パスワード<_o3a_p /> PasswordFormat<_o3a_p/> PasswordSalt<_o3a_p/>
Clear MySecret! 0 tTnkPlesqissc2y2SMEygA==
ハッシュ 2oXm6sZHWbTHFgjgkGQsc2Ec9ZM= 1 wFgjUfhdUFOCKQiI61vtiQ==
暗号化 62RZgDvhxykkqsMchZ0Yly7HS6onhpaoCYaRxV8g0F4CW56OXUU3e7Inza9j9BKp 2 LSRzhGS/aa/oqAXGLHJNBw==

表 1: パスワード MySecret を格納するときの Password-Related フィールドの値の例

手記

SqlMembershipProvider で使用される特定の暗号化またはハッシュ アルゴリズムは、<machineKey> 要素の設定によって決まります。

ロールとロールの関連付けの保存

Roles フレームワークを使用すると、開発者はロールのセットを定義し、どのユーザーがどのロールに属するかを指定できます。 この情報は、aspnet_Rolesaspnet_UsersInRolesの 2 つのテーブルを使用してデータベースにキャプチャされます。 aspnet_Roles テーブル内の各レコードは、特定のアプリケーションのロールを表します。 aspnet_Users テーブルと同様に、aspnet_Roles テーブルには、説明に関連する 3 つの列があります。

  • RoleId
  • RoleName
  • ApplicationId

RoleId は主キー (および型 uniqueidentifier) です。 RoleNamenvarchar(256)型です。 ApplicationId は、ユーザー アカウントを aspnet_Applicationsの特定のアプリケーションにリンクします。 RoleName 列と ApplicationId 列には複合 UNIQUE 制約があり、特定のアプリケーションで各ロール名が一意であることを確認します。

aspnet_UsersInRoles テーブルは、ユーザーとロールの間のマッピングとして機能します。 UserIdRoleId の 2 つの列のみが存在し、複合主キーを構成します。

手順 4: プロバイダーを指定し、その設定をカスタマイズする

メンバーシップフレームワークやロール フレームワークなど、プロバイダー モデルをサポートするすべてのフレームワークには実装の詳細がなく、代わりにその責任をプロバイダー クラスに委任します。 Membership フレームワークの場合、Membership クラスはユーザー アカウントを管理するための API を定義しますが、ユーザー ストアと直接やり取りすることはありません。 代わりに、Membership クラスのメソッドは、構成されたプロバイダーに要求を渡します。SqlMembershipProviderを使用します。 Membership クラスのいずれかのメソッドを呼び出すと、Membership フレームワークが SqlMembershipProviderへの呼び出しを委任する方法はどのようにわかりますか?

Membership クラスには、メンバーシップ フレームワークで使用できる登録されているすべてのプロバイダー クラスへの参照を含む Providers プロパティ があります。 登録された各プロバイダーには、名前と種類が関連付けられています。 この名前は、Providers コレクション内の特定のプロバイダーを参照するためのわかりやすい方法を提供しますが、型はプロバイダー クラスを識別します。 さらに、登録されている各プロバイダーに構成設定を含めることができます。 Membership フレームワークの構成設定には、passwordFormatrequiresUniqueEmailなどがあります。 SqlMembershipProviderで使用される構成設定の完全な一覧については、表 2 を参照してください。

Providers プロパティの内容は、Web アプリケーションの構成設定を使用して指定します。 既定では、すべての Web アプリケーションには、SqlMembershipProvider型の AspNetSqlMembershipProvider という名前のプロバイダーがあります。 この既定のメンバーシップ プロバイダーは、machine.config に登録されています(%WINDIR%\Microsoft.Net\Framework\v2.0.50727\CONFIG))。

警告

探しているサンプルが移動したようです。 私たちはこれを解決することに取り組んでいますのでご安心ください。

上のマークアップに示すように、<membership> 要素 では Membership フレームワークの構成設定が定義され、<providers> 子要素 登録されたプロバイダーが指定されます。 プロバイダーは、<add> または <remove> 要素を使用して追加または削除できます。<clear> 要素を使用して、現在登録されているすべてのプロバイダーを削除します。 上のマークアップに示すように、machine.configSqlMembershipProvider型の AspNetSqlMembershipProvider という名前のプロバイダーを追加します。

name 属性と type 属性に加えて、<add> 要素には、さまざまな構成設定の値を定義する属性が含まれています。 表 2 に、使用可能な SqlMembershipProvider固有の構成設定と、それぞれの説明を示します。

手記

表 2 に示されている既定値は、SqlMembershipProvider クラスで定義されている既定値を参照します。 AspNetSqlMembershipProvider のすべての構成設定が、SqlMembershipProvider クラスの既定値に対応しているわけではないことに注意してください。 たとえば、メンバーシップ プロバイダーで指定されていない場合、requiresUniqueEmail 設定は既定で true になります。 ただし、AspNetSqlMembershipProvider では、falseの値を明示的に指定することで、この既定値がオーバーライドされます。

設定<_o3a_p/> 説明<_o3a_p/>
ApplicationName Membership フレームワークを使用すると、1 つのユーザー ストアを複数のアプリケーション間でパーティション分割できます。 この設定は、メンバーシップ プロバイダーによって使用されるアプリケーション パーティションの名前を示します。 この値が明示的に指定されていない場合は、実行時にアプリケーションの仮想ルート パスの値に設定されます。
commandTimeout SQL コマンドのタイムアウト値 (秒単位) を指定します。 既定値は 30 です。
connectionStringName ユーザー ストア データベースへの接続に使用する <connectionStrings> 要素内の接続文字列の名前。 この値は必須です。
description 登録されたプロバイダーのわかりやすい説明を提供します。
enablePasswordRetrieval ユーザーが忘れたパスワードを取得できるかどうかを指定します。 既定値は falseです。
enablePasswordReset ユーザーが自分のパスワードをリセットできるかどうかを示します。 既定値は trueです。
maxInvalidPasswordAttempts ユーザーがロックアウトされるまでの、指定した passwordAttemptWindow 中に特定のユーザーに対して発生する可能性があるログイン試行の失敗の最大数。既定値は 5 です。
minRequiredNonalphanumericCharacters ユーザーのパスワードに表示する必要がある英数字以外の文字の最小数。 この値は 0 から 128 の間である必要があります。既定値は 1 です。
minRequiredPasswordLength パスワードに必要な最小文字数。 この値は 0 から 128 の間である必要があります。既定値は 7 です。
name 登録済みプロバイダーの名前。 この値は必須です。
passwordAttemptWindow 失敗したログイン試行が追跡される時間 (分)。 ユーザーがこの指定された期間内 maxInvalidPasswordAttempts 無効なログイン資格情報を指定した場合、ユーザーはロックアウトされます。既定値は 10 です。
PasswordFormat パスワード ストレージ形式: ClearHashed、または Encrypted。 既定値は Hashedです。
passwordStrengthRegularExpression 指定した場合、この正規表現は、新しいアカウントを作成するとき、またはパスワードを変更するときに、ユーザーが選択したパスワードの強度を評価するために使用されます。 既定値は空の文字列です。
requiresQuestionAndAnswer ユーザーが自分のパスワードを取得またはリセットするときに、セキュリティの質問に回答する必要があるかどうかを指定します。 既定値は trueです。
requiresUniqueEmail 特定のアプリケーション パーティション内のすべてのユーザー アカウントに一意の電子メール アドレスが必要かどうかを示します。 既定値は trueです。
type プロバイダーの型を指定します。 この値は必須です。

表 2: メンバーシップと SqlMembershipProvider 構成設定

AspNetSqlMembershipProviderに加えて、他のメンバーシップ プロバイダーは、Web.config ファイルに同様のマークアップを追加することで、アプリケーションごとに登録できます。

手記

Roles フレームワークは、ほとんど同じように動作します。machine.config には既定の登録済みロール プロバイダーがあり、登録されたプロバイダーは、Web.configのアプリケーションごとにカスタマイズできます。 今後のチュートリアルでは、Roles フレームワークとその構成マークアップについて詳しく説明します。

SqlMembershipProvider設定のカスタマイズ

既定の SqlMembershipProvider (AspNetSqlMembershipProvider) には、connectionStringName 属性が LocalSqlServerに設定されています。 AspNetSqlMembershipProvider プロバイダーと同様に、接続文字列名 LocalSqlServermachine.configで定義されます。

警告

探しているサンプルが移動したようです。 私たちはこれを解決することに取り組んでいますのでご安心ください。

ご覧のとおり、この接続文字列は、|DataDirectory|aspnetdb.mdf にある SQL 2005 Express Edition データベースを定義しています。 文字列 |DataDirectory|は実行時に ~/App_Data/ ディレクトリを指すために変換されるため、データベース パス |DataDirectory|aspnetdb.mdf" は ~/App_Data/aspnet.mdfに変換されます。

アプリケーションの Web.config ファイルにメンバーシップ プロバイダー情報を指定しなかった場合、アプリケーションは既定の登録済みメンバーシップ プロバイダーである AspNetSqlMembershipProviderを使用します。 ~/App_Data/aspnet.mdf データベースが存在しない場合、ASP.NET ランタイムによって自動的に作成され、アプリケーション サービス スキーマが追加されます。 ただし、aspnet.mdf データベースは使用しません。代わりに、手順 2 で作成した SecurityTutorials.mdf データベースを使用します。 この変更は、次の 2 つの方法のいずれかで実行できます。

  • 接続文字列名の値を指定します。 接続文字列名の値を上書きすることで、既定の登録済みメンバーシップ プロバイダー () を使用して、 データベースで正しく動作させることができます。 この方法は、AspNetSqlMembershipProviderで指定された構成設定に満足している場合は問題ありません。 この手法の詳細については、Scott Guthrie のブログ記事「SQL Server 2000 または SQL Server 2005を使用するための ASP.NET 2.0 Application Services の構成」を参照してください。
  • 型の新しい登録済みプロバイダーを追加し、データベースを指す設定を構成します。 この方法は、データベース接続文字列に加えて他の構成プロパティをカスタマイズする場合に便利です。 自分のプロジェクトでは、柔軟性と読みやすさのために常にこのアプローチを使用しています。

SecurityTutorials.mdf データベースを参照する新しい登録済みプロバイダーを追加する前に、まず Web.config<connectionStrings> セクションに適切な接続文字列値を追加する必要があります。 次のマークアップは、App_Data フォルダー内の SQL Server 2005 Express Edition SecurityTutorials.mdf データベースを参照する SecurityTutorialsConnectionString という名前の新しい接続文字列を追加します。

警告

探しているサンプルが移動したようです。 私たちはこれを解決することに取り組んでいますのでご安心ください。

手記

代替データベース ファイルを使用している場合は、必要に応じて接続文字列を更新します。 正しい接続文字列の形成の詳細については、ConnectionStrings.comを参照してください。

次に、次のメンバーシップ構成マークアップを Web.config ファイルに追加します。 このマークアップは、SecurityTutorialsSqlMembershipProviderという名前の新しいプロバイダーを登録します。

警告

探しているサンプルが移動したようです。 私たちはこれを解決することに取り組んでいますのでご安心ください。

上記のマークアップでは、SecurityTutorialsSqlMembershipProvider プロバイダーの登録に加えて、(<membership> 要素の defaultProvider 属性を使用して) SecurityTutorialsSqlMembershipProvider を既定のプロバイダーとして定義します。 メンバーシップ フレームワークには、複数の登録済みプロバイダーを含めることができることを思い出してください。 AspNetSqlMembershipProvidermachine.configの最初のプロバイダーとして登録されるため、特に指定しない限り、既定のプロバイダーとして機能します。

現在、アプリケーションには、AspNetSqlMembershipProviderSecurityTutorialsSqlMembershipProviderの 2 つの登録済みプロバイダーがあります。 ただし、SecurityTutorialsSqlMembershipProvider プロバイダーを登録する前に、<add> 要素の直前に <clear /> 要素 追加することで、以前に登録されたすべてのプロバイダーをクリアできました。 これにより、登録されたプロバイダーの一覧から AspNetSqlMembershipProvider が消去されます。つまり、SecurityTutorialsSqlMembershipProvider が唯一の登録済みメンバーシップ プロバイダーになります。 この方法を使用した場合は、SecurityTutorialsSqlMembershipProvider を既定のプロバイダーとしてマークする必要はありません。これは、登録されているメンバーシップ プロバイダーのみであるためです。 <clear />の使用方法の詳細については、「プロバイダーを追加するときの <clear /> の使用」を参照してください。

SecurityTutorialsSqlMembershipProviderconnectionStringName 設定では、追加した SecurityTutorialsConnectionString 接続文字列の名前が参照され、その applicationName 設定が SecurityTutorials の値に設定されていることに注意してください。 さらに、requiresUniqueEmail 設定は trueに設定されています。 その他の構成オプションはすべて、AspNetSqlMembershipProviderの値と同じです。 必要に応じて、ここで構成を自由に変更してください。 たとえば、1 文字ではなく 2 つの英数字以外の文字を必要とするか、パスワードの長さを 7 文字ではなく 8 文字に増やして、パスワードの強度を強化できます。

手記

Membership フレームワークを使用すると、1 つのユーザー ストアを複数のアプリケーション間でパーティション分割できます。 メンバーシップ プロバイダーの applicationName 設定は、ユーザー ストアを操作するときにプロバイダーが使用するアプリケーションを示します。 applicationName が明示的に設定されていない場合は、実行時に Web アプリケーションの仮想ルート パスに割り当てられるため、applicationName 構成設定の値を明示的に設定することが重要です。 これは、アプリケーションの仮想ルート パスが変更されない限り正常に動作しますが、アプリケーションを別のパスに移動すると、applicationName の設定も変更されます。 この場合、メンバーシップ プロバイダーは、以前に使用したアプリケーション パーティションとは異なるアプリケーション パーティションの操作を開始します。 移動前に作成されたユーザー アカウントは別のアプリケーション パーティションに存在し、それらのユーザーはサイトにログインできなくなります。 この問題の詳細については、「ASP.NET 2.0 メンバーシップとその他のプロバイダーを構成するときに、 プロパティを常に設定する を参照してください。

概要

この時点で、構成済みのアプリケーション サービス (SecurityTutorials.mdf) を含むデータベースがあり、メンバーシップ フレームワークが登録した SecurityTutorialsSqlMembershipProvider プロバイダーを使用するように Web アプリケーションを構成しました。 この登録済みプロバイダーは SqlMembershipProvider 型であり、その connectionStringName を適切な接続文字列 (SecurityTutorialsConnectionString) に設定し、その applicationName 値を明示的に設定します。

これで、アプリケーションから Membership フレームワークを使用する準備ができました。 次のチュートリアルでは、新しいユーザー アカウントを作成する方法について説明します。 その後、ユーザーの認証、ユーザー ベースの承認の実行、および追加のユーザー関連情報のデータベースへの格納について説明します。

ハッピープログラミング!

もっと読む

このチュートリアルで説明するトピックの詳細については、次のリソースを参照してください。

このチュートリアルに含まれるトピックに関するビデオ トレーニング

作成者について

複数の ASP/ASP.NET 書籍の著者であり、4GuysFromRolla.com の創設者である Scott Mitchell は、1998 年から Microsoft Web テクノロジを使用しています。 Scott は、独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の本は 『Sams Teach Yourself ASP.NET 2.0 in 24 Hours』です。 Scott は、mitchell@4guysfromrolla.com または http://ScottOnWriting.NETのブログからアクセスできます。

特別な謝意を表します

このチュートリアル シリーズは、多くの役に立つ校閲者によってレビューされました。 このチュートリアルのリード レビュー担当者は、Alicja Maziarz でした。 今後の MSDN 記事の確認に関心がありますか? もしそうなら、mitchell@4GuysFromRolla.comに連絡してください。