ユーザー アカウントを作成する (C#)

作成者: Scott Mitchell

注意

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

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

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

このチュートリアルでは、メンバーシップ フレームワーク (SqlMembershipProvider を使用) を使用して新しいユーザー アカウントを作成する方法について説明します。 プログラムと ASP を使用して新しいユーザーを作成する方法について説明します。NET の組み込みの CreateUserWizard コントロール。

はじめに

前のチュートリアルでは、データベースにアプリケーション サービス スキーマをインストールしました。これにより、 と SqlRoleProviderSqlMembershipProvider必要なテーブル、ビュー、およびストアド プロシージャが追加されました。 これにより、このシリーズのチュートリアルの残りの部分に必要なインフラストラクチャが作成されました。 このチュートリアルでは、メンバーシップ フレームワーク (を使用) を使用して SqlMembershipProvider新しいユーザー アカウントを作成する方法について説明します。 プログラムと ASP を使用して新しいユーザーを作成する方法について説明します。NET の組み込みの CreateUserWizard コントロール。

新しいユーザー アカウントを作成する方法を学習するだけでなく、「フォーム認証の概要」チュートリアルで最初に作成したデモ Web サイトを更新してから、「フォーム認証の構成と高度なトピック」チュートリアルで強化する必要があります。 デモ Web アプリケーションには、ハードコーディングされたユーザー名とパスワードのペアに対してユーザーの資格情報を検証するログイン ページがあります。 さらに、 Global.asax 認証されたユーザーのカスタム IPrincipal オブジェクトと IIdentity オブジェクトを作成するコードも含まれています。 ログイン ページを更新して、メンバーシップ フレームワークに対するユーザーの資格情報を検証し、カスタム プリンシパルと ID ロジックを削除します。

それでは作業を始めましょう。

フォーム認証とメンバーシップチェックリスト

メンバーシップ フレームワークの使用を開始する前に、この時点に到達するために実行した重要な手順を確認しましょう。 フォーム ベースの認証シナリオで Membership フレームワークを と共 SqlMembershipProvider に使用する場合は、Web アプリケーションでメンバーシップ機能を実装する前に、次の手順を実行する必要があります。

  1. フォーム ベースの認証を有効にします。フォーム認証の概要」で説明したように、フォーム認証は、要素の mode 属性FormsWeb.config に編集して設定<authentication>することで有効になります。 フォーム認証が有効になっている場合、各受信要求は フォーム認証チケットを調べ、要求元を識別します (存在する場合)。
  2. アプリケーション サービス スキーマを適切なデータベースに追加します。SqlMembershipProvider 使用する場合は、アプリケーション サービス スキーマをデータベースにインストールする必要があります。 通常、このスキーマは、アプリケーションのデータ モデルを保持するのと同じデータベースに追加されます。 SQL Serverのメンバーシップ スキーマの作成に関するチュートリアルでは、ツールをaspnet_regsql.exe使用してこれを実現する方法について説明しました。
  3. Web アプリケーションの設定をカスタマイズして、手順 2. でデータベースを参照します。 SQL Serverのメンバーシップ スキーマの作成に関するチュートリアルでは、手順 2 で選択したデータベースを 使用するように SqlMembershipProvider Web アプリケーションを構成する 2 つの方法を示しました。接続文字列名をLocalSqlServer変更するか、メンバーシップ フレームワーク プロバイダーの一覧に新しい登録済みプロバイダーを追加し、手順 2 のデータベースを使用するように新しいプロバイダーをカスタマイズします。

および フォーム ベースの認証を使用 SqlMembershipProvider する Web アプリケーションを構築する場合は、 クラスまたは ASP.NET Login Web コントロールを Membership 使用する前に、次の 3 つの手順を実行する必要があります。 前のチュートリアルで既にこれらの手順を実行したので、メンバーシップ フレームワークの使用を開始する準備ができました。

手順 1: 新しい ASP.NET ページの追加

このチュートリアルと次の 3 つでは、メンバーシップに関連するさまざまな機能について説明します。 これらのチュートリアル全体で調べられたトピックを実装するには、一連の ASP.NET ページが必要です。 これらのページを作成してから、サイト マップ ファイル (Web.sitemap)を作成しましょう。

まず、 という名前 Membershipのプロジェクトに新しいフォルダーを作成します。 次に、5 つの新しい ASP.NET ページをフォルダーに Membership 追加し、各ページをマスター ページに Site.master リンクします。 ページに次の名前を付けます。

  • CreatingUserAccounts.aspx
  • UserBasedAuthorization.aspx
  • EnhancedCreateUserWizard.aspx
  • AdditionalUserInfo.aspx
  • Guestbook.aspx

この時点で、プロジェクトのソリューション エクスプローラーは図 1 に示すスクリーン ショットのようになります。

メンバーシップ フォルダーに 5 つの新しいページが追加されました

図 1: フォルダーに Membership 5 つの新しいページが追加されました (フルサイズの画像を表示する をクリックします)

各ページには、この時点で、マスター ページの ContentPlaceHolders MainContentLoginContentごとに 1 つずつと という 2 つのコンテンツ コントロールが必要です。

<asp:Content ID="Content1" ContentPlaceHolderID="MainContent"

Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="LoginContent"
Runat="Server">
</asp:Content>

ContentPlaceHolder の LoginContent 既定のマークアップには、ユーザーが認証されているかどうかに応じて、サイトにログオンまたはログオフするためのリンクが表示されることを思い出してください。 ただし、Content コントロールが Content2 存在すると、マスター ページの既定のマークアップがオーバーライドされます。 フォーム認証の概要に関するチュートリアルで説明したように、これは、左側の列にログイン関連のオプションを表示しないページで役立ちます。

ただし、これら 5 つのページでは、ContentPlaceHolder のマスター ページの既定のマークアップを LoginContent 表示する必要があります。 そのため、Content コントロールの宣言型マークアップを Content2 削除します。 その後、5 つのページのマークアップのそれぞれに 1 つのコンテンツ コントロールのみを含める必要があります。

手順 2: サイト マップの作成

最も簡単な Web サイト以外はすべて、何らかの形式のナビゲーション ユーザー インターフェイスを実装する必要があります。 ナビゲーション ユーザー インターフェイスは、サイトのさまざまなセクションへのリンクの単純な一覧である場合があります。 または、これらのリンクをメニューまたはツリー ビューに配置することもできます。 ページ開発者は、ナビゲーション ユーザー インターフェイスの作成は、ストーリーの半分にすぎません。 また、サイトの論理構造を保守可能で更新可能な方法で定義するための手段も必要です。 新しいページが追加されたり、既存のページが削除されたりすると、1 つのソース (サイト マップ) を更新し、それらの変更をサイトのナビゲーション ユーザー インターフェイス全体に反映できるようにする必要があります。

サイト マップを定義し、サイト マップに基づいてナビゲーション ユーザー インターフェイスを実装する 2 つのタスクは、サイト マップ フレームワークと、ASP.NET バージョン 2.0 で追加されたナビゲーション Web コントロールのおかげで簡単に実行できます。 サイト マップ フレームワークを使用すると、開発者はサイト マップを定義し、プログラム API (クラス) を使用してサイト マップにSiteMapアクセスできます。 組み込みのナビゲーション Web コントロールには、 Menu コントロールTreeView コントロールおよび SiteMapPath コントロールが含まれます。

メンバーシップおよびロール フレームワークと同様に、サイト マップ フレームワークは プロバイダー モデルの上に構築されます。 Site Map プロバイダー クラスのジョブは、XML ファイルやデータベース テーブルなどの永続的なデータ ストアから、 クラスによって SiteMap 使用されるメモリ内構造を生成することです。 .NET Frameworkには、XML ファイル (XmlSiteMapProvider) からサイト マップ データを読み取る既定のサイト マップ プロバイダーが付属しています。これは、このチュートリアルで使用するプロバイダーです。 いくつかの別のサイト マップ プロバイダーの実装については、このチュートリアルの最後にある「その他の読み取り」セクションを参照してください。

既定のサイト マップ プロバイダーでは、 という名前 Web.sitemap の適切な形式の XML ファイルがルート ディレクトリに存在することを想定しています。 この既定のプロバイダーを使用しているため、このようなファイルを追加し、適切な XML 形式でサイト マップの構造を定義する必要があります。 ファイルを追加するには、ソリューション エクスプローラーでプロジェクト名を右クリックし、[新しい項目の追加] を選択します。 ダイアログ ボックスで、 という名前 Web.sitemapのサイト マップの種類のファイルを追加することを選択します。

Web.sitemap という名前のファイルをプロジェクトのルート ディレクトリに追加する

図 2: プロジェクトのルート ディレクトリにという名前 Web.sitemap のファイルを追加する (フルサイズの画像を表示する をクリックします)

XML サイト マップ ファイルは、Web サイトの構造を階層として定義します。 この階層関係は、 要素の祖先を介して XML ファイルで <siteMapNode> モデル化されます。 はWeb.sitemap、正確に 1 つの<siteMapNode>子を<siteMap>持つ親ノードで始まる必要があります。 この最上位要素 <siteMapNode> は階層のルートを表し、任意の数の子孫ノードを持つことができます。 各<siteMapNode>要素には 属性をtitle含める必要があり、必要に応じて および description 属性を含urlめることができます。空urlでない各属性は一意である必要があります。

ファイルに次の XML を Web.sitemap 入力します。

<?xml version="1.0" encoding="utf-8" ?>

<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
     <siteMapNode url="~/Default.aspx" title="Home">
          <siteMapNode title="Membership">
               <siteMapNode url="~/Membership/CreatingUserAccounts.aspx" title="Creating User Accounts" />

               <siteMapNode url="~/Membership/UserBasedAuthorization.aspx" title="User-Based Authorization" />
               <siteMapNode url="~/Membership/Guestbook.aspx" title="Storing Additional User Information" />
          </siteMapNode>

     </siteMapNode>
</siteMap>

上のサイト マップ マークアップでは、図 3 に示す階層が定義されています。

サイト マップは階層ナビゲーション構造を表します

図 3: サイト マップは階層ナビゲーション構造を表します (フルサイズの画像を表示する をクリックします)

手順 3: ナビゲーション ユーザー インターフェイスを含むようにマスター ページを更新する

ASP.NET には、ユーザー インターフェイスを設計するためのナビゲーション関連の Web コントロールが多数含まれています。 これには、Menu、TreeView、および SiteMapPath コントロールが含まれます。 Menu コントロールと TreeView コントロールは、それぞれメニューまたはツリーにサイト マップ構造をレンダリングしますが、SiteMapPath には、アクセスされている現在のノードとその先祖を示す階層リンクが表示されます。 サイト マップ データは、SiteMapDataSource を使用して他のデータ Web コントロールにバインドでき、 クラスを介してプログラムで SiteMap アクセスできます。

Site Map フレームワークとナビゲーション コントロールの詳細な説明は、このチュートリアル シリーズの範囲を超えているので、独自のナビゲーション ユーザー インターフェイスの作成に時間を費やすのではなく、リピータ コントロールを使用してナビゲーション リンクの 2 つの深い箇条書きを表示する 、ASP.NET 2.0 のチュートリアル シリーズの「データの操作」で使用するものを借りてみましょう。 図 4 に示すように、

このインターフェイスを作成するには、マスター ページの左側の列に次の宣言マークアップを Site.master 追加します。ここで、"TODO: Menu will go here.." というテキストが表示されます。は現在存在します。

<ul>
     <li>

          <asp:HyperLink runat="server" ID="lnkHome" NavigateUrl="~/Default.aspx">Home</asp:HyperLink>
     </li>
     <asp:Repeater runat="server" ID="menu" DataSourceID="SiteMapDataSource1">

          <ItemTemplate>
               <li>
                    <asp:HyperLink ID="lnkMenuItem" runat="server" 
                         NavigateUrl='<%# Eval("Url") %>'><%# Eval("Title") %></asp:HyperLink>

                    <asp:Repeater ID="submenu" runat="server" DataSource="<%#
                         ((SiteMapNode) Container.DataItem).ChildNodes %>">
                         <HeaderTemplate>
                              <ul>
                         </HeaderTemplate>
                         <ItemTemplate>

                              <li>
                                   <asp:HyperLink ID="lnkMenuItem" runat="server" NavigateUrl='<%#
                                        Eval("Url") %>'><%# Eval("Title") %></asp:HyperLink>

                              </li>
                         </ItemTemplate>
                         <FooterTemplate>
                              </ul>
                         </FooterTemplate>
                    </asp:Repeater>
               </li>
          </ItemTemplate>
     </asp:Repeater>

</ul>
    
<asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" ShowStartingNode="false" />

上記のマークアップは、 という名前 menu の Repeater コントロールを SiteMapDataSource にバインドし、 で Web.sitemap定義されているサイト マップ階層を返します。 SiteMapDataSource コントロールの ShowStartingNode プロパティ は False に設定されているため、"Home" ノードの子孫からサイト マップの階層が返されます。 Repeater は、これらの各ノード (現在は "メンバーシップ" のみ) を <li> 要素に表示します。 もう 1 つの内部 Repeater は、現在のノードの子を入れ子になった順序付けされていないリストに表示します。

図 4 は、上記のマークアップのレンダリングされた出力と、手順 2 で作成したサイト マップ構造を示しています。 Repeater は、バニラの順序付けされていないリスト マークアップをレンダリングします。で Styles.css 定義されているカスケード スタイル シートルールは、美的に快適なレイアウトを担当します。 上記のマークアップのしくみの詳細については、 マスター ページとサイト ナビゲーション のチュートリアルを参照してください。

ナビゲーション ユーザー インターフェイスは、入れ子になった順序付けされていないリストを使用してレンダリングされます

図 4: ナビゲーション ユーザー インターフェイスは、入れ子になった順序なしのリストを使用してレンダリングされます (フルサイズの画像を表示する をクリックします)

階層リンク ナビゲーションの追加

左側の列のリンクの一覧に加えて、各ページに 階層リンクを表示させてみましょう。 階層リンクは、ユーザーがサイト階層内の現在の位置をすばやく表示するナビゲーション ユーザー インターフェイス要素です。 SiteMapPath コントロールは、サイト マップ フレームワークを使用してサイト マップ内の現在のページの位置を決定し、この情報に基づいて階層リンクを表示します。

具体的には、マスター ページのヘッダー<div>要素に 要素を追加<span>し、新しい<span>要素のclass属性を "階層リンク" に設定します。 (クラスには Styles.css 、"階層リンク" クラスのルールが含まれています)。次に、この新しい <span> 要素に SiteMapPath を追加します。

<div id="header">
     <span class="title">User Account Tutorials</span><br />
     <span class="breadcrumb">
          <asp:SiteMapPath ID="SiteMapPath1" runat="server">

          </asp:SiteMapPath>
     </span>
</div>

図 5 は、 にアクセスするときの SiteMapPath の出力を ~/Membership/CreatingUserAccounts.aspx示しています。

階層リンクサイト マップに現在のページとその先祖が表示されます

図 5: 階層リンクサイト マップに現在のページとその先祖が表示されます (フルサイズの画像を表示する をクリックします)

手順 4: カスタム プリンシパルと ID ロジックを削除する

カスタム プリンシパルオブジェクトと ID オブジェクトは、認証されたユーザーに関連付けることができます。 これを実現するには、 で Global.asax アプリケーションの PostAuthenticateRequest イベントのイベント ハンドラーを作成します。これは、 がユーザーを認証した後 FormsAuthenticationModule に発生します。 このイベント ハンドラーでは、 によってFormsAuthenticationModule追加された GenericPrincipal オブジェクトと FormsIdentity オブジェクトを、そのチュートリアルで作成した CustomPrincipal オブジェクトと CustomIdentity オブジェクトに置き換えました。

カスタム プリンシパル オブジェクトと ID オブジェクトは特定のシナリオで役立ちますが、ほとんどの場合、 GenericPrincipal オブジェクトと FormsIdentity オブジェクトで十分です。 したがって、私はデフォルトの動作に戻る価値があると思います。 この変更を行うには、イベント ハンドラーを削除またはコメントアウト PostAuthenticateRequest するか、ファイルを完全に Global.asax 削除します。

手順 5: プログラムによって新しいユーザーを作成する

Membership フレームワークを使用して新しいユーザー アカウントを作成するには、 クラスの CreateUser メソッドMembership使用します。 このメソッドには、ユーザー名、パスワード、およびその他のユーザー関連フィールドの入力パラメーターがあります。 呼び出し時に、新しいユーザー アカウントの作成を構成済みのメンバーシップ プロバイダーに委任し、作成したばかりのユーザー アカウントを表すオブジェクトを返MembershipUserします。

CreateUserメソッドには 4 つのオーバーロードがあり、それぞれが異なる数の入力パラメーターを受け入れます。

これら 4 つのオーバーロードは、収集される情報の量によって異なります。 たとえば、最初のオーバーロードでは、新しいユーザー アカウントのユーザー名とパスワードだけが必要ですが、2 つ目のオーバーロードではユーザーのメール アドレスも必要です。

これらのオーバーロードは、新しいユーザー アカウントの作成に必要な情報がメンバーシップ プロバイダーの構成設定によって異なるため、存在します。 SQL Serverチュートリアルのメンバーシップ スキーマの作成で、 でWeb.configメンバーシップ プロバイダーの構成設定を指定することを確認しました。 表 2 には、構成設定の完全な一覧が含まれていました。

このようなメンバーシップ プロバイダー構成設定の 1 つは、使用できるオーバーロードに影響をrequiresQuestionAndAnswerCreateUserえる設定です。 が (既定値) にtrue設定されている場合requiresQuestionAndAnswerは、新しいユーザー アカウントを作成するときに、セキュリティの質問と回答を指定する必要があります。 この情報は、ユーザーがパスワードをリセットまたは変更する必要がある場合に後で使用されます。 具体的には、その時点でセキュリティの質問が表示され、パスワードをリセットまたは変更するために正しい回答を入力する必要があります。 したがって、 が にtrue設定されている場合requiresQuestionAndAnswer、最初の 2 つのCreateUserオーバーロードのいずれかを呼び出すと、セキュリティの質問と回答がないため、例外が発生します。 現在、アプリケーションはセキュリティの質問と回答を必要とするように構成されているため、ユーザーをプログラムで作成するときは、後者の 2 つのオーバーロードのいずれかを使用する必要があります。

メソッドを CreateUser 使用して説明するために、ユーザー インターフェイスを作成し、ユーザーに名前、パスワード、電子メール、定義済みのセキュリティの質問に対する回答を求めます。 フォルダー内の CreatingUserAccounts.aspx ページを Membership 開き、次の Web コントロールを Content コントロールに追加します。

  • という名前の TextBox Username
  • プロパティが に設定されている という名前PasswordTextModeの TextBoxPassword
  • という名前の TextBox Email
  • そのプロパティがTextクリアされたという名前SecurityQuestionのラベル
  • という名前の TextBox SecurityAnswer
  • Text プロパティが "ユーザー アカウントの作成" に設定されているという名前 CreateAccountButton の Button
  • プロパティがクリアされた という名前 CreateAccountResultsText Label コントロール

この時点で、画面は図 6 に示すスクリーン ショットのようになります。

CreatingUserAccounts.aspx ページにさまざまな Web コントロールを追加する

図 6: ページにさまざまな Web コントロールを CreatingUserAccounts.aspx 追加する (フルサイズの画像を表示する をクリックします)

SecurityQuestion Label と SecurityAnswer TextBox は、定義済みのセキュリティの質問を表示し、ユーザーの回答を収集することを目的としています。 セキュリティの質問と回答の両方がユーザーごとに格納されるため、各ユーザーが独自のセキュリティの質問を定義できるようにすることができます。 しかし、この例では、私は普遍的なセキュリティの質問、すなわち「あなたのお気に入りの色は何ですか?」を使用することにしました。

この定義済みのセキュリティ質問を実装するには、 という名前 passwordQuestionのページの分離コード クラスに定数を追加し、セキュリティの質問を割り当てます。 次にPage_Load、イベント ハンドラーで、この定数を Label Text の プロパティにSecurityQuestion割り当てます。

const string passwordQuestion = "What is your favorite color";
    
protected void Page_Load(object sender, EventArgs e)
{
     if (!Page.IsPostBack)
          SecurityQuestion.Text = passwordQuestion;
}

次に、 の イベントのイベント ハンドラーをCreateAccountButtonClick作成し、次のコードを追加します。

protected void CreateAccountButton_Click(object sender, EventArgs e)
{
     MembershipCreateStatus createStatus;
     MembershipUser newUser = Membership.CreateUser(Username.Text, Password.Text, Email.Text, passwordQuestion, SecurityAnswer.Text, true, out createStatus);
     switch (createStatus)
     {
          case MembershipCreateStatus.Success:
               CreateAccountResults.Text = "The user account was successfully created!";
               break;
          case MembershipCreateStatus.DuplicateUserName:
               CreateAccountResults.Text = "There already exists a user with this username.";
               break;

          case MembershipCreateStatus.DuplicateEmail:
               CreateAccountResults.Text = "There already exists a user with this email address.";
               break;
          case MembershipCreateStatus.InvalidEmail:
               CreateAccountResults.Text = "There email address you provided in invalid.";
               break;
          case MembershipCreateStatus.InvalidAnswer:
               CreateAccountResults.Text = "There security answer was invalid.";
               break;
          case MembershipCreateStatus.InvalidPassword:
               CreateAccountResults.Text = "The password you provided is invalid. It must be seven characters long and have at least one non-alphanumeric character.";

               break;
          default:
               CreateAccountResults.Text = "There was an unknown error; the user account was NOT created.";
               break;
     }
}

イベント ハンドラーはClick、型 MembershipCreateStatusという名前createStatusの変数を定義することから始まります。 MembershipCreateStatus は、操作の CreateUser 状態を示す列挙体です。 たとえば、ユーザー アカウントが正常に作成されると、結果 MembershipCreateStatus のインスタンスは の Success値に設定されます。一方、同じユーザー名を持つユーザーが既に存在するため、操作が失敗した場合は、 の DuplicateUserName値に設定されます。 使用するCreateUserオーバーロードでは、 パラメーターとして out インスタンスを MembershipCreateStatus メソッドに渡す必要があります。 このパラメーターは メソッド内 CreateUser の適切な値に設定され、メソッド呼び出し後にその値を調べて、ユーザー アカウントが正常に作成されたかどうかを判断できます。

を呼び出 CreateUserした後、 ステートメント createStatusswitch 使用して、 に割り当てられた値に応じて適切なメッセージを createStatus出力します。 図 7 は、新しいユーザーが正常に作成された場合の出力を示しています。 図 8 と図 9 は、ユーザー アカウントが作成されていない場合の出力を示しています。 図 8 では、訪問者が 5 文字のパスワードを入力しました。これは、メンバーシップ プロバイダーの構成設定に示されているパスワード強度要件を満たしていません。 図 9 では、訪問者は既存のユーザー名 (図 7 で作成されたもの) を使用してユーザー アカウントを作成しようとしています。

新しいユーザー アカウントが正常に作成されました

図 7: 新しいユーザー アカウントが正常に作成されました (クリックするとフルサイズの画像が表示されます)

指定されたパスワードが弱すぎるため、ユーザー アカウントが作成されない

図 8: 指定されたパスワードが弱すぎるため、ユーザー アカウントが作成されない (フルサイズの画像を表示する をクリックします)

ユーザー名が既に使用されているため、ユーザー アカウントは作成されません

図 9: ユーザー名が既に使用されているため、ユーザー アカウントが作成されない (フルサイズの画像を表示する をクリックします)

注意

最初の 2 つの CreateUser メソッド オーバーロードの 1 つを使用するときに成功または失敗を判断する方法が疑問に思われるかもしれません。どちらも 型 MembershipCreateStatusのパラメーターを持つものもありません。 これらの最初の 2 つのオーバーロードは、エラーが発生した場合に例外をスローMembershipCreateUserExceptionします。これには、 型MembershipCreateStatusの プロパティがStatusCode含まれます。

いくつかのユーザー アカウントを作成した後、データベース内の テーブルと aspnet_Membership テーブルSecurityTutorials.mdfの内容を一覧表示して、アカウントがaspnet_Users作成されていることを確認します。 図 10 に示すように、ページを介して Tito と Bruce という 2 人のユーザーを CreatingUserAccounts.aspx 追加しました。

メンバーシップ ユーザー ストアには、Tito と Bruce の 2 人のユーザーがいます

図 10: メンバーシップ ユーザー ストアには Tito と Bruce の 2 人のユーザーがいます (フルサイズの画像を表示する をクリックします)

メンバーシップ ユーザー ストアには Bruce と Tito のアカウント情報が含まれるようになりましたが、Bruce または Tito がサイトにログオンできるようにする機能はまだ実装されていません。 現在、 は、 Login.aspx ハードコーディングされたユーザー名とパスワードのペアのセットに対してユーザーの資格情報を検証します。メンバーシップ フレームワークに対して指定された資格情報は検証 されません 。 ここでは、 テーブルと aspnet_Membership テーブルにaspnet_Users新しいユーザー アカウントを表示すれば十分です。 次のチュートリアルメンバーシップ ユーザー ストアに対するユーザー資格情報の検証」では、メンバーシップ ストアに対して検証するようにログイン ページを更新します。

注意

データベースに SecurityTutorials.mdf ユーザーが表示されない場合は、Web アプリケーションで既定のメンバーシップ プロバイダー AspNetSqlMembershipProvider(データベースをユーザー ストアとして使用) が使用 ASPNETDB.mdf されていることが原因である可能性があります。 これが問題かどうかを判断するには、ソリューション エクスプローラーの [更新] ボタンをクリックします。 という名前 ASPNETDB.mdf のデータベースがフォルダーに App_Data 追加されている場合は、これが問題です。 メンバーシップ プロバイダーを適切に構成する方法についてはSQL Server チュートリアルの「メンバーシップ スキーマの作成」の手順 4 に戻ります。

ほとんどのユーザー アカウントの作成シナリオでは、訪問者には、ユーザー名、パスワード、電子メール、その他の重要な情報を入力するためのインターフェイスが表示され、その時点で新しいアカウントが作成されます。 この手順では、このようなインターフェイスを手動で構築し、 メソッドを使用 Membership.CreateUser して、ユーザーの入力に基づいて新しいユーザー アカウントをプログラムで追加する方法を確認しました。 ただし、このコードでは、新しいユーザー アカウントを作成しました。 作成したばかりのユーザー アカウントでユーザーをサイトにログインさせる、確認メールをユーザーに送信するなどのフォローアップ アクションは実行されませんでした。 これらの追加の手順では、Button のイベント ハンドラーに追加の Click コードが必要になります。

ASP.NET は、ユーザー アカウント作成プロセスを処理するように設計された CreateUserWizard コントロールに付属しています。新しいユーザー アカウントを作成するためのユーザー インターフェイスのレンダリングから、Membership フレームワークでのアカウントの作成、アカウント作成後のタスクの実行 (確認メールの送信や、作成したユーザーのサイトへのログ記録など)。 CreateUserWizard コントロールの使用は、ツールボックスからページに CreateUserWizard コントロールをドラッグし、いくつかのプロパティを設定するのと同じくらい簡単です。 ほとんどの場合、1 行のコードを記述する必要はありません。 この細かいコントロールについては、手順 6 で詳しく説明します。

新しいユーザー アカウントが一般的な [アカウントの作成] Web ページでのみ作成される場合、CreateUserWizard コントロールがニーズを満たす可能性が高く、メソッドを使用 CreateUser するコードを記述する必要はほとんどありません。 ただし、この方法は、 CreateUser 高度にカスタマイズされたアカウントの作成ユーザー エクスペリエンスが必要なシナリオや、別のインターフェイスを使用してプログラムで新しいユーザー アカウントを作成する必要がある場合に便利です。 たとえば、ユーザーが他のアプリケーションからのユーザー情報を含む XML ファイルをアップロードできるページがあるとします。 ページは、アップロードされた XML ファイルの内容を解析し、 メソッドを呼び出して XML で表される各ユーザーの新しいアカウントを CreateUser 作成する場合があります。

手順 6: CreateUserWizard コントロールを使用して新しいユーザーを作成する

ASP.NET には、多数のログイン Web コントロールが付属しています。 これらのコントロールは、多くの一般的なユーザー アカウントとログイン関連のシナリオに役立っています。 CreateUserWizard コントロールは、Membership フレームワークに新しいユーザー アカウントを追加するためのユーザー インターフェイスを提示するように設計されたそのようなコントロールの 1 つです。

他の多くのログイン関連 Web コントロールと同様に、CreateUserWizard は 1 行のコードを記述せずに使用できます。 メンバーシップ プロバイダーの構成設定に基づいて直感的にユーザー インターフェイスを提供し、ユーザーが必要な情報を Membership 入力して [ユーザーの作成] ボタンをクリックした後、クラスの CreateUser メソッドを内部的に呼び出します。 CreateUserWizard コントロールは非常にカスタマイズ可能です。 アカウント作成プロセスのさまざまな段階で発生するイベントのホストがあります。 必要に応じてイベント ハンドラーを作成して、カスタム ロジックをアカウント作成ワークフローに挿入できます。 さらに、CreateUserWizard の外観は非常に柔軟です。 既定のインターフェイスの外観を定義するプロパティは多数あります。必要に応じて、コントロールをテンプレートに変換するか、追加のユーザー登録 "ステップ" を追加できます。

まず、CreateUserWizard コントロールの既定のインターフェイスと動作の使用を見てみましょう。 次に、コントロールのプロパティとイベントを使用して外観をカスタマイズする方法について説明します。

CreateUserWizard の既定のインターフェイスと動作の確認

フォルダー内の CreatingUserAccounts.aspx ページに Membership 戻り、デザイン モードまたは分割モードに切り替えて、ページの上部に CreateUserWizard コントロールを追加します。 CreateUserWizard コントロールは、[ツールボックス] の [ログイン コントロール] セクションにファイルされます。 コントロールを追加した後、そのプロパティを IDRegisterUser設定します。 図 11 のスクリーン ショットに示すように、CreateUserWizard は、新しいユーザーのユーザー名、パスワード、電子メール アドレス、セキュリティの質問と回答のテキスト ボックスを含むインターフェイスをレンダリングします。

CreateUserWizard コントロールは、汎用の Create ユーザー インターフェイスをレンダリングします

図 11: CreateUserWizard コントロールは、汎用 Create ユーザー インターフェイスをレンダリングします (フルサイズの画像を表示する をクリックします)

CreateUserWizard コントロールによって生成された既定のユーザー インターフェイスと、手順 5 で作成したインターフェイスを比較してみましょう。 まず、CreateUserWizard コントロールを使用すると、訪問者はセキュリティの質問と回答の両方を指定できます。一方、手動で作成したインターフェイスでは事前に定義されたセキュリティの質問が使用されています。 CreateUserWizard コントロールのインターフェイスには検証コントロールも含まれていますが、インターフェイスのフォーム フィールドに対する検証はまだ実装されていませんでした。 CreateUserWizard コントロール インターフェイスには、"パスワードの確認" テキスト ボックスが含まれています ("パスワード" テキスト ボックスと "パスワードの比較" テキスト ボックスが等しいことを確認するための CompareValidator と共に)。

興味深いのは、CreateUserWizard コントロールが、ユーザー インターフェイスをレンダリングするときにメンバーシップ プロバイダーの構成設定を参照することです。 たとえば、セキュリティの質問と回答のテキスト ボックスは、 が True に設定されている場合 requiresQuestionAndAnswer にのみ表示されます。 同様に、CreateUserWizard は、RegularExpressionValidator コントロールを自動的に追加して、パスワード強度の要件が満たされていることを確認し、、minRequiredNonalphanumericCharacters、、および の構成設定にminRequiredPasswordLength基づいて、 ErrorMessage および ValidationExpression プロパティをpasswordStrengthRegularExpression設定します。

CreateUserWizard コントロールの名前が示すように、 Wizard コントロールから派生します。 ウィザード コントロールは、複数ステップのタスクを完了するためのインターフェイスを提供するように設計されています。 ウィザード コントロールには、任意の数の WizardStepsがあり、それぞれが、そのステップの HTML コントロールと Web コントロールを定義するテンプレートです。 ウィザード コントロールは最初に、最初 WizardStepの をナビゲーション コントロールと共に表示します。このコントロールを使用すると、ユーザーは 1 つのステップから次のステップに進んだり、前の手順に戻ったりできます。

図 11 の宣言型マークアップに示すように、CreateUserWizard コントロールの既定のインターフェイスには、2 つの WizardSteps:

  • CreateUserWizardStep – インターフェイスをレンダリングして、新しいユーザー アカウントを作成するための情報を収集します。 これは図 11 に示す手順です。
  • CompleteWizardStep – アカウントが正常に作成されたことを示すメッセージをレンダリングします。

CreateUserWizard の外観と動作は、これらの手順のいずれかをテンプレートに変換するか、独自 WizardStepsの を追加することによって変更できます。 登録インターフェイスに を WizardStep 追加する方法については、 追加のユーザー情報の保存 に関するチュートリアルを参照してください。

CreateUserWizard コントロールの動作を見てみましょう。 ブラウザーから CreatingUserAccounts.aspx ページにアクセスします。 まず、CreateUserWizard のインターフェイスに無効な値を入力します。 パスワード強度の要件に準拠していないパスワードを入力するか、[ユーザー名] ボックスを空のままにします。 CreateUserWizard に適切なエラー メッセージが表示されます。 図 12 は、強力なパスワードが不十分なユーザーを作成しようとしたときの出力を示しています。

CreateUserWizard によって検証コントロールが自動的に挿入される

図 12: CreateUserWizard によって検証コントロールが自動的に挿入される (クリックするとフルサイズの画像が表示されます)

次に、CreateUserWizard に適切な値を入力し、[ユーザーの作成] ボタンをクリックします。 必須フィールドが入力されており、パスワードの強度が十分であると仮定すると、CreateUserWizard は Membership フレームワークを使用して新しいユーザー アカウントを作成し、そのインターフェイスを CompleteWizardStep表示します (図 13 を参照)。 CreateUserWizard は、手順 5 で行ったのと同じように、バックグラウンドで メソッドを呼び出します Membership.CreateUser

新しいユーザー アカウントが正常に作成されました

図 13: 新しいユーザー アカウントが正常に作成されました (クリックするとフルサイズの画像が表示されます)

注意

図 13 に示すように、 CompleteWizardStepのインターフェイスには [続行] ボタンが含まれています。 ただし、この時点でクリックするとポストバックが実行され、訪問者は同じページに残ります。 「CreateUserWizard の外観と動作のプロパティを使用したカスタマイズ」セクションでは、このボタンから訪問者を (または他のページ) に送信する Default.aspx 方法について説明します。

新しいユーザー アカウントを作成した後、Visual Studio に戻り、図 10 のように テーブルと aspnet_Membership テーブルを調べてaspnet_Users、アカウントが正常に作成されたことを確認します。

CreateUserWizard のプロパティを使用した動作と外観のカスタマイズ

CreateUserWizard は、プロパティ、、およびイベント ハンドラーを使用して、 WizardStepsさまざまな方法でカスタマイズできます。 このセクションでは、プロパティを使用してコントロールの外観をカスタマイズする方法について説明します。次のセクションでは、イベント ハンドラーを使用してコントロールの動作を拡張する方法について説明します。

CreateUserWizard コントロールの既定のユーザー インターフェイスに表示される事実上すべてのテキストは、多数のプロパティを使用してカスタマイズできます。 たとえば、テキスト ボックスの左側に表示される "User Name"、"Password"、"Confirm Password"、"E-mail"、"Security Question"、および "Security Answer" ラベルは、それぞれ 、PasswordLabelTextEmailLabelTextConfirmPasswordLabelTextQuestionLabelTextおよび AnswerLabelText プロパティでUserNameLabelTextカスタマイズできます。 同様に、 と の [Create User]\(ユーザーの作成\) ボタンと [Continue]\(続行\) ボタンCreateUserWizardStepCompleteWizardStepのテキストを指定するためのプロパティと、ボタンが Buttons、LinkButtons、または ImageButtons としてレンダリングされる場合は、プロパティがあります。

色、罫線、フォント、およびその他のビジュアル要素は、スタイル プロパティのホストを通じて構成できます。 CreateUserWizard コントロール自体には、共通の Web コントロール スタイル プロパティ ( BackColorBorderStyleCssClassFont、 など) があり、CreateUserWizard のインターフェイスの特定のセクションの外観を定義するためのスタイル プロパティがいくつかあります。 たとえば、 プロパティは TextBoxStyleCreateUserWizardStepのテキスト ボックスのスタイルを定義しますTitleTextStyleが、 プロパティはタイトルのスタイルを定義します ("新しいアカウントにサインアップ")。

外観関連のプロパティに加えて、CreateUserWizard コントロールの動作に影響を与えるプロパティがいくつかあります。 プロパティを DisplayCancelButtonTrue に設定すると、[ユーザーの作成] ボタンの横に [キャンセル] ボタンが表示されます (既定値は False です)。 [キャンセル] ボタンを表示する場合は、[キャンセル] をクリックした後にユーザーが送信するページを指定する プロパティも必ず設定CancelDestinationPageUrlしてください。 前のセクションで説明したように、 の インターフェイスの CompleteWizardStep[続行] ボタンをクリックするとポストバックが発生しますが、訪問者は同じページに残ります。 [続行] ボタンをクリックした後、訪問者を他のページに送信するには、 プロパティに ContinueDestinationPageUrlURL を指定するだけです。

CreateUserWizard コントロールを RegisterUser 更新して、[キャンセル] ボタンを表示し、[キャンセル] ボタンまたは [続行] ボタンがクリックされたときに訪問者 Default.aspx をに送信してみましょう。 これを行うには、 プロパティを DisplayCancelButton True に設定し、 プロパティと ContinueDestinationPageUrl プロパティのCancelDestinationPageUrl両方を "~/Default.aspx" に設定します。 図 14 は、ブラウザーで表示された更新された CreateUserWizard を示しています。

CreateUserWizardStep にはキャンセル ボタンが含まれています

図 14: キャンセル CreateUserWizardStep ボタンを含む (フルサイズの画像を表示するクリック)

訪問者がユーザー名、パスワード、メール アドレス、セキュリティの質問と回答を入力し、[ユーザーの作成] をクリックすると、新しいユーザー アカウントが作成され、その新しく作成されたユーザーとして訪問者がログインします。 ページにアクセスするユーザーが自分で新しいアカウントを作成していると仮定すると、これが望ましい動作である可能性があります。 ただし、管理者が新しいユーザー アカウントを追加できるようにする場合があります。 そうすることで、ユーザー アカウントは作成されますが、管理者は (新しく作成されたアカウントとしてではなく) 管理者としてログインしたままになります。 この動作は、Boolean LoginCreatedUser プロパティを使用して変更できます。

メンバーシップ フレームワークのユーザー アカウントには、承認されたフラグが含まれています。承認されていないユーザーは、サイトにログインできません。 既定では、新しく作成されたアカウントは承認済みとしてマークされ、ユーザーは直ちにサイトにログインできます。 ただし、新しいユーザー アカウントが未承認としてマークされている可能性があります。 新しいユーザーがログインする前に、管理者が手動で承認する必要がある場合があります。または、ユーザーにログオンを許可する前に、サインアップ時に入力されたメール アドレスが有効であることを確認したい場合があります。 どのような場合でも、CreateUserWizard コントロール DisableCreatedUser のプロパティ を True (既定値は False) に設定することで、新しく作成されたユーザー アカウントを未承認としてマークすることができます。

メモの動作関連のその他のプロパティには、 と がありますAutoGeneratePasswordMailDefinition。 プロパティが AutoGeneratePassword True に設定されている場合、 CreateUserWizardStep には [パスワード] テキスト ボックスと [パスワードの確認] テキスト ボックスは表示されません。代わりに、新しく作成されたユーザーのパスワードは、クラスの GeneratePassword メソッドMembership使用して自動的に生成されます。 メソッドは GeneratePassword 、指定した長さのパスワードを作成し、構成されたパスワード強度要件を満たすのに十分な数の英数字以外の文字を使用します。

プロパティはMailDefinition、アカウントの作成プロセス中に指定された電子メール アドレスに電子メールを送信する場合に便利です。 MailDefinitionプロパティには、構築された電子メール メッセージに関する情報を定義するための一連のサブプロパティが含まれています。 これらのサブプロパティには、、、 FromCCPriorityIsBodyHtmlなどのSubjectオプションがBodyFileName含まれます。 プロパティはBodyFileName、電子メール メッセージの本文を含むテキストファイルまたは HTML ファイルを指します。 本文では、 と <%Password%>という 2 つの定義済みのプレースホルダーがサポートされています<%UserName%>。 これらのプレースホルダーは、ファイルに存在する BodyFileName 場合は、作成したユーザーの名前とパスワードに置き換えられます。

注意

コントロールの MailDefinition プロパティはCreateUserWizard、新しいアカウントの作成時に送信される電子メール メッセージの詳細のみを指定します。 電子メール メッセージの実際の送信方法 (つまり、SMTP サーバーとメール ドロップ ディレクトリのどちらが使用されているか、認証情報など) に関する詳細は含まれません。 これらの低レベルの詳細は、 の セクションWeb.configで定義する<system.net>必要があります。 これらの構成設定の詳細と、ASP.NET 2.0 からの電子メールの送信に関する一般的な情報については、「SystemNetMail.com」の FAQ と「ASP.NET2.0 でEmailを送信する」の記事を参照してください。

イベント ハンドラーを使用した CreateUserWizard の動作の拡張

CreateUserWizard コントロールは、ワークフロー中に多数のイベントを発生させます。 たとえば、訪問者がユーザー名、パスワード、およびその他の関連情報を入力し、[ユーザーの作成] ボタンをクリックすると、CreateUserWizard コントロールによってイベントがCreatingUser発生します。 作成プロセス中に問題が発生した CreateUserError 場合は、イベント が発生します。ただし、ユーザーが正常に作成されると、 CreatedUser イベント が発生します。 発生する CreateUserWizard コントロール イベントが追加されていますが、これらは 3 つの最もドイツ語的なイベントです。

特定のシナリオでは、CreateUserWizard ワークフローを利用できます。これを行うには、適切なイベントのイベント ハンドラーを作成します。 これを説明するために、CreateUserWizard コントロールを RegisterUser 拡張して、ユーザー名とパスワードにカスタム検証を含めましょう。 特に、CreateUserWizard を拡張して、ユーザー名に先頭または末尾のスペースを含めず、ユーザー名をパスワードのどこにも表示できないようにしましょう。 つまり、誰かが "Scott" のようなユーザー名を作成したり、"Scott" や "Scott.1234" などのユーザー名とパスワードの組み合わせを行ったりできないようにしたいと考えています。

これを実現するには、追加の検証チェックを実行するイベントの CreatingUser イベント ハンドラーを作成します。 指定されたデータが無効な場合は、作成プロセスをキャンセルする必要があります。 また、ラベル Web コントロールをページに追加して、ユーザー名またはパスワードが無効であることを説明するメッセージを表示する必要があります。 まず、CreateUserWizard コントロールの下に Label コントロールを追加し、そのプロパティを IDInvalidUserNameOrPasswordMessage 設定し、その ForeColor プロパティを に設定します Red。 プロパティをクリアし、その Text プロパティと Visible プロパティを EnableViewState False に設定します。

<asp:Label runat="server" id="InvalidUserNameOrPasswordMessage"
     Visible="false" ForeColor="Red" EnableViewState="false">

</asp:Label>

次に、CreateUserWizard コントロールのイベントのイベント ハンドラーを CreatingUser 作成します。 イベント ハンドラーを作成するには、Designerでコントロールを選択し、プロパティ ウィンドウに移動します。 そこから稲妻アイコンをクリックし、適切なイベントをダブルクリックしてイベント ハンドラーを作成します。

CreatingUser イベント ハンドラーに次のコードを追加します。

protected void RegisterUser_CreatingUser(object sender, LoginCancelEventArgs e)
{
     string trimmedUserName = RegisterUser.UserName.Trim();
     if (RegisterUser.UserName.Length != trimmedUserName.Length)
     {
          // Show the error message
          InvalidUserNameOrPasswordMessage.Text = "The username cannot contain leading or trailing spaces.";
          InvalidUserNameOrPasswordMessage.Visible = true;

          // Cancel the create user workflow
          e.Cancel = true;
     }
     else
     {
          // Username is valid, make sure that the password does not contain the username

          if (RegisterUser.Password.IndexOf(RegisterUser.UserName, StringComparison.OrdinalIgnoreCase) >= 0)
          {
               // Show the error message
               InvalidUserNameOrPasswordMessage.Text = "The username may not appear anywhere in the password.";
               InvalidUserNameOrPasswordMessage.Visible = true;
               // Cancel the create user workflow
               e.Cancel = true;
          }
     }
}

CreateUserWizard コントロールに入力したユーザー名とパスワードは、それぞれ プロパティ UserNamePassword プロパティを通じて使用できます。 上記のイベント ハンドラーでは、これらのプロパティを使用して、指定されたユーザー名に先頭または末尾のスペースが含まれているかどうか、およびユーザー名がパスワード内で見つかったかどうかを判断します。 これらの条件のいずれかが満たされた場合、エラー メッセージが Label に InvalidUserNameOrPasswordMessage 表示され、イベント ハンドラーの e.Cancel プロパティが に true設定されます。 が にtrue設定されている場合e.Cancel、CreateUserWizard はワークフローをショートサーキットし、ユーザー アカウントの作成プロセスを実質的に取り消します。

図 15 は、ユーザーが先頭に CreatingUserAccounts.aspx スペースを含むユーザー名を入力したときのスクリーン ショットを示しています。

先頭または末尾のスペースを持つユーザー名は許可されません

図 15: 先頭または末尾のスペースを持つユーザー名は許可されていません (フルサイズの画像を表示するをクリックします)

注意

CreateUserWizard コントロールのイベントの使用例については、追加のユーザー情報のCreatedUser格納に関するチュートリアルを参照してください。

まとめ

クラスの CreateUser メソッドはMembership、Membership フレームワークに新しいユーザー アカウントを作成します。 これは、構成されたメンバーシップ プロバイダーへの呼び出しを委任することによって行われます。 のSqlMembershipProvider場合、 メソッドは CreateUser および aspnet_Membership データベース テーブルにレコードをaspnet_Users追加します。

(手順 5 で説明したように) 新しいユーザー アカウントはプログラムで作成できますが、より高速で簡単な方法は CreateUserWizard コントロールを使用することです。 このコントロールは、ユーザー情報を収集し、メンバーシップ フレームワークで新しいユーザーを作成するためのマルチステップ ユーザー インターフェイスをレンダリングします。 このコントロールの下では、手順 5 で確認したのと同じ Membership.CreateUser 方法が使用されますが、コントロールはユーザー インターフェイス、検証コントロールを作成し、コードのなめしを記述しなくてもユーザー アカウント作成エラーに応答します。

この時点で、新しいユーザー アカウントを作成する機能が用意されています。 ただし、ログイン ページでは、2 番目のチュートリアルで指定したハードコーディングされた資格情報に対して検証が行われます。 次の チュートリアル では、メンバーシップ フレームワークに対してユーザーが指定した資格情報を検証するように更新 Login.aspx します。

プログラミングに満足!

もっと読む

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

著者について

複数の ASP/ASP.NET 書籍の著者であり、4GuysFromRolla.com の創設者である Scott Mitchell は、1998 年から Microsoft Web テクノロジと協力しています。 Scott は、独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の本は サムズは24時間で2.0 ASP.NET 自分自身を教えています。 Scott は、 または mitchell@4guysfromrolla.com のブログから http://ScottOnWriting.NETアクセスできます。

特別な感謝...

このチュートリアル シリーズは、多くの役に立つ校閲者によってレビューされました。 このチュートリアルのリードレビュー担当者はテレサ・マーフィーでした。 今後の MSDN の記事を確認することに関心がありますか? その場合は、 に mitchell@4GuysFromRolla.com行をドロップしてください。