メンバーシップ
作成者: Microsoft
Note
この記事が作成された後で、ASP.NET メンバーシップ プロバイダーは ASP.NET Identity に置き換えられました。 この記事が作成された時点で使われていたメンバーシップ プロバイダーではなく、 ASP.NET Identity プラットフォームを使うようにアプリを更新することを強くお勧めします。 ASP.NET メンバーシップ システムと比べると、ASP.NET Identity には次のような多くの利点があります。
- パフォーマンスの向上
- 向上した拡張性とテストの容易性
- OAuth、OpenID Connect、2 要素認証のサポート
- クレームベースの ID のサポート
- ASP.Net Core との相互運用性の向上
ASP.NET のメンバーシップは、ASP.NET 1.x からのフォーム認証モデルの成功に基づいています。 ASP.NET フォーム認証を使うと、ログイン フォームを ASP.NET アプリケーションに組み込み、データベースや他のデータ ストアに対してユーザーを検証する便利な方法が提供されます。
ASP.NET のメンバーシップは、ASP.NET 1.x からのフォーム認証モデルの成功に基づいています。 ASP.NET フォーム認証を使うと、ログイン フォームを ASP.NET アプリケーションに組み込み、データベースや他のデータ ストアに対してユーザーを検証する便利な方法が提供されます。 FormsAuthentication クラスのメンバーを使うと、認証用に Cookie を処理したり、有効なログインを確認したり、ユーザーをログアウトさせたりできます。ただし、ASP.NET 1.x アプリケーションでフォーム認証を実装するには、かなりの量のコードが必要になる場合があります。
ASP.NET 2.0 のメンバーシップを使うと、フォーム認証だけを使う場合より大きく進歩します。 (メンバーシップは、フォーム認証と組み合わせると最も堅牢になりますが、フォーム認証の使用は必須ではありません。)すぐにわかるように、ASP.NET のメンバーシップと ASP.NET 2.0 のログイン コントロールを使うと、コードをほとんど記述せずに強力なメンバーシップ システムを実装できます。
ASP.NET 2.0 でのメンバーシップの実装
メンバーシップの実装は、次の 4 つのステップで行います。 関連する多くのサブステップと、実装できるオプションの構成があることに注意してください。 これらの手順は、メンバーシップの構成の全体像を示すためのものです。
メンバーシップ データベースを作成します (SQL Server がメンバーシップ ストアとして使われている場合)。
アプリケーション構成ファイルでメンバーシップのオプションを指定します。 (メンバーシップは既定で有効になります。)
使用するメンバーシップ ストアの種類を決定します。 オプションは次のとおりです。
- Microsoft SQL Server (バージョン 7.0 以降)
- Active Directory ストア
- カスタム メンバーシップ プロバイダー
ASP.NET フォーム認証用にアプリケーションを構成します。 繰り返しますが、メンバーシップはフォーム認証を利用するように設計されていますが、フォーム認証の使用は必須ではありません。
メンバーシップ用のユーザー アカウントを定義し、必要に応じてロールを構成します。
メンバーシップ データベースの作成
メンバーシップ ストアとして SQL Server 7.0 以降をお使いの場合は、aspnet_regsql ユーティリティ (Visual Studio .NET 2005 のコマンド プロンプトから入手するのが最も簡単です) を使って、データベースを構成できます。 aspnet_regsql ユーティリティは、コマンド プロンプト ツールとして、または GUI ウィザードから、使用できます。 最も簡単にデータベースを構成できるのはウィザードの方法です。 次のコマンドを実行するだけで、ウィザードにアクセスできます。
aspnet_regsql W
そのコマンドを実行すると、次に示すように、ASP.NET SQL Server セットアップ ウィザードが表示されます。
図 1
ASP.NET SQL Server セットアップ ウィザードは、ユーザーがウィザードで指定したインスタンスに Web サイトを作成します。 ただし、ASP.NET は、machine.config ファイル内の接続文字列を使ってデータベースに接続します。 既定では、この接続文字列は SQL Server 2005 のインスタンスを指しているので、SQL Server 2000 または SQL Server 7.0 のインスタンスをお使いの場合は、machine.config ファイルの接続文字列を変更する必要があります。 その接続文字列は、次の場所にあります。
<configuration>
<connectionStrings>
<add name="LocalSqlServer"
connectionString="data source=(local);
Integrated Security=SSPI;Initial Catalog=aspnetdb;"
providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>
残念ながら、接続文字列を変更しない場合、ASP.NET ではわかりやすいエラーが表示されません。 データベースを作成していないというエラーを示し続けるだけです。 上記の場合、ローカル環境の SQL Server 2000 のインスタンスを指すように接続文字列を変更しました。
構成の指定およびユーザーとロールの追加
メンバーシップ構成の次のステップは、アプリケーションの web.config ファイルに必要な情報を追加することです。 ASP.NET 1.x では、lowerCamelCase が使われていて、Intellisense がないため、web.config ファイルの変更が困難な場合がありました。 Visual Studio .NET 2005 では、構成ファイル用の Intellisense によってタスクがはるかに簡単になりますが、ASP.NET 2.0 では、構成ファイル編集用の Web インターフェイスが提供されてさらに 1 歩進みます。
次に示すように、ソリューション エクスプローラーのツール バーの [ASP.NET 構成] ボタンをクリックして、Web インターフェイスを起動できます。 ログイン コントロールを挿入すると表示されるポップアップを使って Web インターフェイスを起動することもできます。
図 2
これにより、次に示す ASP.NET Web サイト管理ツールが起動します。 ASP.NET Web サイト管理は 4 つのタブから成るインターフェイスであり、アプリケーションの設定を簡単に管理できます。 次のタブがあります。
- ホーム
- セキュリティ: ユーザー、ロール、アクセスを構成します。
- アプリケーション: アプリケーションの設定を構成します。
- プロバイダー: アプリケーションのメンバーシップ プロバイダーを構成してテストします。
Web サイト管理ツールを使うと、新しいユーザーの作成、新しいロールの作成、ユーザーとロールの管理を簡単に行うことができます。 この機能は、Windows インターフェイスでは使用できません。 Windows インターフェイスを使うと、認可の設定を簡単に定義し、プロバイダーを追加、削除、管理できます。これは、Web サイト管理ツールにはない機能です。
Windows インターフェイスを起動するには、インターネット インフォメーション サービス スナップインを開き、アプリケーションを右クリックして、[プロパティ] を選びます。 [ASP.NET] タブをクリックした後、[構成の編集] ボタンをクリックします。 ([構成の編集] ボタンが有効になるには、アプリケーションが ASP.NET 2.0 で実行されている必要があります。ASP.NET ダイアログで ASP.NET のバージョンを構成することもできます。)次に示すような [ASP.NET 構成の設定] ダイアログが表示されます。
図 3
[全般] タブに、接続文字列とアプリケーションの設定が表示されます。 斜体の設定は親構成ファイル (machine.config またはより高いレベルの web.config) で定義されており、斜体ではない設定はアプリケーション構成ファイルから取得されます。 アプリケーション レベルで設定が追加、削除、または編集された場合、ASP.NET は、継承元の構成ファイルからその設定を削除するのではなく、アプリケーション レベルの web.config で設定を追加、削除、または変更します。
[認証] タブを次に示します。 ここでは、メンバーシップの設定を構成します。 フォーム認証の設定、メンバーシップ プロバイダー、ロール プロバイダーを、ここで構成できます。
図 4
アプリケーションでのメンバーシップの実装
アプリケーションで ASP.NET 2.0 メンバーシップを実装する最も簡単な方法は、提供されているログオン コントロールを使うことです。 この方法を使うと、コードをまったく書くことなく、ASP.NET 2.0 メンバーシップの基本を実装できます。
ASP.NET 2.0 では、次のログオン コントロールを使用できます。
Login コントロール
Login コントロールは、ユーザーがメンバーシップ システムにログインするためのインターフェイスを提供します。 ユーザー名とパスワードのテキスト ボックスおよびログイン ボタンを備えています。 まだ登録していないユーザーが登録するためのリンク、次回以降のアクセス時にユーザーが自動的にログインできるようにするチェック ボックス、パスワード リマインダーのリンクなど。Login コントロールのすべての機能は、コントロールのプロパティを使ってカスタマイズできます。
ASP.NET 1.x では、開発者はフォーム認証の使用時に参照を行うためのコードをかなり記述する必要がありました。 ASP.NET 2.0 メンバーシップでは、コードをまったく記述せずにユーザーを検証できます。 ASP.NET がユーザーの検索を自動的に行います。 (ASP.NET メンバーシップを使わずに Login コントロールを使っている場合は、OnAuthenticate メソッドを使ってユーザーを検証できます。)
LoginView コントロール
LoginView コントロールはテンプレート コントロールであり、AnonymousTemplate と LoggedInTemplate の 2 つのテンプレートを既定で提供します。 表示されるテンプレートは、ユーザーがメンバーシップ システムにログインしているかどうかによって決まります。 通常、このコントロールは、ユーザーがまだログインしていない場合は Login コントロールを表示し、ユーザーがログインしている場合は LoginStatus コントロールや他のログイン コントロールを表示するために使われます。 ASP.NET アプリケーションでロール管理を使っている場合、LoginView コントロールは、ユーザー ロールに基づいて特定のテンプレートを表示できます。 (ASP.NET のロール管理については、後で詳しく説明します。)
PasswordRecovery コントロール
PasswordRecovery コントロールを使うと、ユーザーは自分の現在のパスワードについてのメールを受け取ったり、自分のパスワードをリセットしたりできます。 クリア テキストのパスワードと暗号化されたパスワードを回復し、ユーザーにメールで送信できます。 パスワードがハッシュされている場合は、回復できません。 代わりに、ユーザーはパスワードのリセットを実行する必要があります。
LoginStatus コントロール
LoginStatus コントロールは、ログインしていないユーザーにはログイン インジケーターを表示し、現在ログインしているユーザーにはログアウト インジケーターを表示するために使われます。 表示するインジケーターを決めるには、Request.IsAuthenticated プロパティが使われます。 LoginStatus コントロールでは、テキスト (LoginText と LogoutText プロパティによって実装されます) または画像 (LoginImageUrl と LogoutImageUrl プロパティによって実装されます) でインジケーターを表示できます。
ユーザーが LoginStatus コントロールを使ってログアウトすると、LogoutPageUrl プロパティで指定されている URL にリダイレクトされます。 そのプロパティが設定されていない場合は、現在のページが更新されます。 サイトはフォーム認証によって保護されている可能性が高いため、現在のページを更新すると、ユーザーはサイトのログイン ページにリダイレクトされます。
LoginName コントロール
LoginName コントロールには、現在サイトにログインしているユーザーのユーザー名が表示されます。
CreateUserWizard コントロール
CreateUserWizard コントロールは、ユーザーがメンバーシップ システムに登録するための便利な方法を提供します。 次に示すインターフェイスを使って、手順 (WizardStep のコレクションとして実装) を追加できます。
図 5
CreateUserWizard はテンプレート コントロールであり、Wizard クラスから派生して、次のテンプレートを提供します。
- HeaderTemplate: このテンプレートは、ウィザードのヘッダーの外観を制御します。
- SidebarTemplate: このテンプレートは、ウィザードのサイドバーの外観を制御します。
- StartNavigationTemplate: このテンプレートは、開始ステップでのウィザードのナビゲーション領域の外観を制御します。
- StepNavigationTemplate: このテンプレートは、開始または終了ステップではないときのナビゲーション領域の外観を制御します。
- FinishNavigationTemplate: このテンプレートは、終了ステップでのナビゲーション領域の外観を制御します。
さらに、ウィザードに追加するステップごとに、そのステップに対する ContentTemplate と CustomNavigationTemplate の両方を含むカスタム テンプレートが ASP.NET によって作成されます。 CreateUserWizard のカスタマイズについて詳しくは、VS.NET 2005 のドキュメントを参照してください。
ChangePassword コントロール
ChangePassword コントロールを使うと、ユーザーは自分のパスワードを変更できます。 DisplayUserName プロパティが true (既定では false) の場合、ユーザーはログインしていなくても自分のパスワードを変更できます。 DisplayUserName プロパティが true の場合、既にログインしているユーザーは、ログインしていない別のユーザーのユーザー ID を知っている場合、そのユーザーのパスワードを変更できます。
ユーザーがログインしなくてもパスワードを変更できるようにする場合は、ChangePassword コントロールが表示されるページで匿名アクセスを許可する必要があることに注意してください。 明らかに、ユーザーが自分のパスワードを変更するためには、古いパスワードを指定する必要があります。
ロール管理
ロール管理を使うと、ユーザーを特定のロールに割り当てた後、そのロールに基づいて特定のファイルまたはフォルダーへのアクセスを制限できます。 ロール管理には API も用意されており、プログラムによって、ユーザーのロールを判別したり、特定のロールのすべてのユーザーを判別したりして、それに応じて対応することができます。
ASP.NET メンバーシップにロール管理は必要なく、ロール管理を使うためにメンバーシップも必要ありません。 ただし、この 2 つはお互いをうまく補完し、開発者はそれらを組み合わせて使う可能性があります。
アプリケーションでロール管理を有効にするには、web.config ファイルを次のように変更します。
<roleManager enabled="true" cacheRolesInCookie="true" cookieProtection="All" />
cacheRolesInCookie 属性が true に設定されていると、ASP.NET はユーザー ロールのメンバーシップをクライアントの Cookie にキャッシュします。 これにより、RoleProvider を呼び出さなくてもロール参照を実行できます。 この属性を使う開発者には、cookieProtection 属性を All に設定することをお勧めします。 (これが既定の設定です)。これにより、Cookie データは確実に暗号化され、Cookie の内容が変更されていないことを確認するのに役立ちます。 ロールは、Web サイト管理ツールを使って追加できます。 それを使うと、ロールを簡単に定義し、それらのロールに基づいてサイトの一部へのアクセスを構成し、ユーザーをロールに割り当てることができます。
図 6
上記のように、ロールの名前を入力してから [ロールの追加] をクリックするだけで、新しいロールを追加できます。 既存のロールの一覧で適切なリンクをクリックして、既存のロールを管理または削除できます。
ロールを管理するときは、次に示すようにユーザーを追加または削除できます。
図 7
[ロールに所属] チェック ボックスをオンにして、ユーザーを特定のロールに簡単に追加できます。 ASP.NET は、適切なエントリを使ってメンバーシップ データベースを自動的に更新します。 また、アプリケーションのアクセス規則を構成することもできます。 ASP.NET 1.x の開発者は、web.config ファイルの <authorization> 要素でこれを行うことに慣れており、ASP.NET 2.0 でもそのオプションを引き続き使用できます。 ただし、以下で示すように、Web サイト管理ツールを使ってアクセス規則を管理する方が簡単です。
図 8
この例では、Administration フォルダーが (薄い灰色なのでわかりにくいですが) 強調表示されていて、Administrators ロールにアクセスが許可されています。 他のユーザーはすべて拒否されています。 頭のアイコンをクリックして規則を選び、[上へ移動] と [下へ移動] ボタンを使って規則を調整できます。 ASP.NET の <authorization> 要素と同様に、規則は表示されている順序で処理されます。 つまり、上の画像の規則を逆の順序にすると、ASP.NET で最初に検出される規則がフォルダーに対してすべてのユーザーを拒否する規則になるため、Administration フォルダーに誰もアクセスできなくなります。
ASP.NET 2.0 では、アクセス規則を指定するフォルダーに web.config ファイルが追加されます。 アクセス規則は、構成ファイルまたは Web サイト管理ツールを使って編集できます。 つまり、Web サイト管理ツールは、構成ファイルを使いやすい環境で編集できるインターフェイスにすぎません。
コードでのロールの使用
ロール管理用の API は、バージョン 1.x から変更されていません。 ユーザーが特定のロールに含まれるかどうかを判断するには、IsInRole メソッドを使います。
if (User.IsInRole(Administrators)) {
btnManageSite.Visible = true;
}
ASP.NET は、現在のコンテキストのメンバーとして RolePrincipal インスタンスも作成します。 RolePrincipal オブジェクトを使うと、ユーザーが属するすべてのロールを次のように取得できます。
string[] userRoles = ((RolePrincipal)User).GetRoles();
LoginView コントロールでの RoleGroups の使用
ロールの管理とメンバーシップについてわかったので、LoginView コントロールで ASP.NET 2.0 のこの機能がどのように利用されているのかを簡単に説明します。 前に説明したように、LoginView コントロールはテンプレート コントロールであり、AnonymousTemplate と LoggedInTemplate の 2 つのテンプレートが既定で含まれます。 [LoginView タスク] ダイアログ内には、RoleGroup を編集できる (以下で示すような) リンクがあります。
図 9
各 RoleGroup オブジェクトには、その RoleGroup が適用されるロールを定義する文字列の配列が含まれています。 LoginView コントロールに新しい RoleGroup を追加するには、[RoleGroups の編集] リンクをクリックします。 上の図では、Administrators に新しい RoleGroup を追加したことがわかります。 [表示] ドロップダウンからその RoleGroup (RoleGroup[0]) を選ぶと、Administrators ロールのメンバーにのみ表示されるテンプレートを構成できます。 次の図では、Sales ロールと Distribution ロールのメンバーに適用される新しい RoleGroup が追加されています。 これにより、[LoginView タスク] ダイアログの [表示] ドロップダウンに 2 つ目の RoleGroup が追加され、そのテンプレートに追加されたものはすべて、Sales または Distribution ロールのすべてのユーザーに表示されます。
図 10
既存のメンバーシップ プロバイダーのオーバーライド
ASP.NET メンバーシップの機能を拡張できる方法はいくつかあります。 まず第一に、当然のことながら、SqlMembershipProvider クラスを継承してそのメソッドをオーバーライドすると、その既存の機能を変更できます。 たとえば、ユーザーの作成時に独自の機能を実装したい場合は、次のように SqlMembershipProvider を継承する独自のクラスを作成できます。
public class jForumMembershipProvider : SqlMembershipProvider {
public jForumMembershipProvider() {
}
public override MembershipUser CreateUser(
string username,
string password,
string email,
string passwordQuestion,
string passwordAnswer,
bool isApproved,
object providerUserKey,
out MembershipCreateStatus status) {
// your own implementation
return base.CreateUser(
username,
password,
email,
passwordQuestion,
passwordAnswer,
isApproved,
providerUserKey,
out status);
}
}
一方、独自のプロバイダーを (たとえば、Access データベースにメンバーシップ情報を格納するために) 作成したい場合は、独自のプロバイダーを作成できます。
独自のメンバーシップ プロバイダーの作成
独自のメンバーシップ プロバイダーを作成するには、まず、MembershipProvider クラスを継承するクラスを作成する必要があります。 VB.NET を使っている場合は、Visual Studio 2005 によって、オーバーライドする必要があるすべてのメソッドのスタブが追加されます。 C# を使っている場合は、自分でスタブを追加する必要があります。
次のものをオーバーライドする必要があります。
- ApplicationName プロパティ
- ChangePassword 関数
- ChangePasswordQuestionAndAnswer 関数
- CreateUser 関数
- DeleteUser 関数
- EnablePasswordReset プロパティ
- EnablePasswordRetrieval プロパティ
- FindUsersByEmail 関数
- FindUsersByName 関数
- GetAllUsers 関数
- GetNumberOfUsersOnline 関数
- GetPassword 関数
- GetUser 関数
- GetUserNameByEmail 関数
- MaxInvalidPasswordAttempts プロパティ
- MinRequiredNonAlphanumericCharacters プロパティ
- MinRequiredPasswordLength プロパティ
- PasswordAttemptWindow プロパティ
- PasswordFormat プロパティ
- PasswordStrengthRegularExpression プロパティ
- RequiresQuestionAndAnswer プロパティ
- RequiresUniqueEmail プロパティ
- ResetPassword 関数
- UnlockUser 関数
- UpdateUser 関数
- ValidateUser 関数
これは、C# 開発者として実装するものの一覧です。 実装を含まない VB.NET でクラスを作成してから、.NET Reflector または同様のツールを使ってコードを C# に変換する方が簡単な場合があります。
接続文字列とその他のプロパティは、Initialize メソッドで既定値に設定する必要があります。 (Initialize メソッドは、プロバイダーが実行時に読み込まれた時点で呼び出されます)。Initialize メソッドの 2 番目のパラメーターは System.Collections.Specialized.NameValueCollection 型であり、web.config ファイルでカスタム プロバイダーに関連付けられている <add> 要素への参照です。 そのエントリは次のようになります。
<system.web>
<authentication mode="Forms"/>
<membership
defaultProvider="jForumCustomMembershipProvider" >
<providers>
<add name="jForumCustomMembershipProvider"
type="jForumCustomMembershipProvider"
requiresQuestionAndAnswer="true"
connectionString="Provider=Microsoft.Jet.
OLEDB.4.0;Data Source=C:\jForumCustomMembershipProvider\
App_Data\Members.mdb;Persist Security
Info=False"
/>
</providers>
</membership>
</system.web>
Initialize メソッドの例を次に示します。
public override void Initialize(string name,
System.Collections.Specialized.NameValueCollection config) {
if (config["requiresQuestionAndAnswer"])
_requiresQuestionAndAnswer = true;
_connString = config["connectionString"];
base.Initialize(name, config);
}
ユーザーがログイン フォームを送信するときにユーザーを検証するには、ValidateUser メソッドを使う必要があります。 このメソッドは、ユーザーが Login コントロールのログイン ボタンをクリックすると呼び出されます。 ユーザーの検索を行うコードをこのメソッドに配置します。
ご覧のように、独自のメンバーシップ プロバイダーの作成は難しくなく、ASP.NET 2.0 のこの強力な機能を拡張できます。