メンバーシップ

作成者: 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 つのステップで行います。 関連する多くのサブステップと、実装できるオプションの構成があることに注意してください。 これらの手順は、メンバーシップの構成の全体像を示すためのものです。

  1. メンバーシップ データベースを作成します (SQL Server がメンバーシップ ストアとして使われている場合)。

  2. アプリケーション構成ファイルでメンバーシップのオプションを指定します。 (メンバーシップは既定で有効になります。)

  3. 使用するメンバーシップ ストアの種類を決定します。 オプションは次のとおりです。

    • Microsoft SQL Server (バージョン 7.0 以降)
    • Active Directory ストア
    • カスタム メンバーシップ プロバイダー
  4. ASP.NET フォーム認証用にアプリケーションを構成します。 繰り返しますが、メンバーシップはフォーム認証を利用するように設計されていますが、フォーム認証の使用は必須ではありません。

  5. メンバーシップ用のユーザー アカウントを定義し、必要に応じてロールを構成します。

メンバーシップ データベースの作成

メンバーシップ ストアとして SQL Server 7.0 以降をお使いの場合は、aspnet_regsql ユーティリティ (Visual Studio .NET 2005 のコマンド プロンプトから入手するのが最も簡単です) を使って、データベースを構成できます。 aspnet_regsql ユーティリティは、コマンド プロンプト ツールとして、または GUI ウィザードから、使用できます。 最も簡単にデータベースを構成できるのはウィザードの方法です。 次のコマンドを実行するだけで、ウィザードにアクセスできます。

aspnet_regsql W

そのコマンドを実行すると、次に示すように、ASP.NET SQL Server セットアップ ウィザードが表示されます。

Screenshot that shows an A S P dot NET S Q L Server Setup Wizard.

図 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 インターフェイスを起動することもできます。

Screenshot that shows a Solution Explorer toolbar with web.config selected.

図 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 構成の設定] ダイアログが表示されます。

Screenshot that shows a General tab on the A S P dot N E T Configuration Settings dialog.

図 3

[全般] タブに、接続文字列とアプリケーションの設定が表示されます。 斜体の設定は親構成ファイル (machine.config またはより高いレベルの web.config) で定義されており、斜体ではない設定はアプリケーション構成ファイルから取得されます。 アプリケーション レベルで設定が追加、削除、または編集された場合、ASP.NET は、継承元の構成ファイルからその設定を削除するのではなく、アプリケーション レベルの web.config で設定を追加、削除、または変更します。

[認証] タブを次に示します。 ここでは、メンバーシップの設定を構成します。 フォーム認証の設定、メンバーシップ プロバイダー、ロール プロバイダーを、ここで構成できます。

Screenshot that shows an Authentication tab on the A S P dot N E T Configurations dialog.

図 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 コントロールでは、テキスト (LoginTextLogoutText プロパティによって実装されます) または画像 (LoginImageUrlLogoutImageUrl プロパティによって実装されます) でインジケーターを表示できます。

ユーザーが LoginStatus コントロールを使ってログアウトすると、LogoutPageUrl プロパティで指定されている URL にリダイレクトされます。 そのプロパティが設定されていない場合は、現在のページが更新されます。 サイトはフォーム認証によって保護されている可能性が高いため、現在のページを更新すると、ユーザーはサイトのログイン ページにリダイレクトされます。

LoginName コントロール

LoginName コントロールには、現在サイトにログインしているユーザーのユーザー名が表示されます。

CreateUserWizard コントロール

CreateUserWizard コントロールは、ユーザーがメンバーシップ システムに登録するための便利な方法を提供します。 次に示すインターフェイスを使って、手順 (WizardStep のコレクションとして実装) を追加できます。

Screenshot that shows a Create User Wizard Tasks dialog with a drop down menu to Sign Up for Your New Account.

図 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 サイト管理ツールを使って追加できます。 それを使うと、ロールを簡単に定義し、それらのロールに基づいてサイトの一部へのアクセスを構成し、ユーザーをロールに割り当てることができます。

Screenshot that shows an A S P dot N E T Web Site Administration Tool with the Add Role button.

図 6

上記のように、ロールの名前を入力してから [ロールの追加] をクリックするだけで、新しいロールを追加できます。 既存のロールの一覧で適切なリンクをクリックして、既存のロールを管理または削除できます。

ロールを管理するときは、次に示すようにユーザーを追加または削除できます。

Screenshot that shows an A S P dot N E T Web Site Administration Tool with the Find User button.

図 7

[ロールに所属] チェック ボックスをオンにして、ユーザーを特定のロールに簡単に追加できます。 ASP.NET は、適切なエントリを使ってメンバーシップ データベースを自動的に更新します。 また、アプリケーションのアクセス規則を構成することもできます。 ASP.NET 1.x の開発者は、web.config ファイルの <authorization> 要素でこれを行うことに慣れており、ASP.NET 2.0 でもそのオプションを引き続き使用できます。 ただし、以下で示すように、Web サイト管理ツールを使ってアクセス規則を管理する方が簡単です。

Screenshot that shows the A S P dot N E T Web Site Administration tool with items selected under Users and Roles.

図 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 を編集できる (以下で示すような) リンクがあります。

Screenshot that shows the Login View control within the Login View Tasks dialog with a drop down and Role Group selected.

図 9

各 RoleGroup オブジェクトには、その RoleGroup が適用されるロールを定義する文字列の配列が含まれています。 LoginView コントロールに新しい RoleGroup を追加するには、[RoleGroups の編集] リンクをクリックします。 上の図では、Administrators に新しい RoleGroup を追加したことがわかります。 [表示] ドロップダウンからその RoleGroup (RoleGroup[0]) を選ぶと、Administrators ロールのメンバーにのみ表示されるテンプレートを構成できます。 次の図では、Sales ロールと Distribution ロールのメンバーに適用される新しい RoleGroup が追加されています。 これにより、[LoginView タスク] ダイアログの [表示] ドロップダウンに 2 つ目の RoleGroup が追加され、そのテンプレートに追加されたものはすべて、Sales または Distribution ロールのすべてのユーザーに表示されます。

Screenshot that shows a Role Group Collection Editor dialog with a dropdown selecting Administrators.

図 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 のこの強力な機能を拡張できます。