パスワードを復元し、変更する (C#)

作成者: Scott Mitchell

Note

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

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

ASP.NET には、パスワードの回復と変更を支援するための 2 つの Web コントロールが含まれています。 PasswordRecovery コントロールを使用すると、訪問者は失われたパスワードを回復できます。 ChangePassword コントロールを使用すると、ユーザーは自分のパスワードを更新できます。 このチュートリアル シリーズで見てきた他のログイン関連の Web コントロールと同様に、PasswordRecovery コントロールと ChangePassword コントロールは、バックグラウンドでメンバーシップ フレームワークと連携して、ユーザーのパスワードをリセットまたは変更します。

はじめに

ほとんどの人がそうであるように、銀行、公益事業会社、電話会社、メール アカウント、パーソナライズされた Web ポータルで、多数の異なるパスワードを覚えておく必要があります。 最近は覚えるべき資格情報が非常に多いため、パスワードを忘れるのは珍しいことではありません。 これを考慮するには、ユーザー アカウントを提供する Web サイトに、ユーザーが自分のパスワードを回復する方法を含める必要があります。 通常、このプロセスでは、新しいランダムなパスワードを生成し、ファイル上のユーザーのメール アドレスにメールで送信します。 新しいパスワードを受け取った後、ほとんどのユーザーはサイトに戻り、ランダムに生成されたパスワードから覚えやすいパスワードに変更します。

ASP.NET には、パスワードの回復と変更を支援するための 2 つの Web コントロールが含まれています。 PasswordRecovery コントロールを使用すると、訪問者は失われたパスワードを回復できます。 ChangePassword コントロールを使用すると、ユーザーは自分のパスワードを更新できます。 このチュートリアル シリーズで見てきた他のログイン関連の Web コントロールと同様に、PasswordRecovery コントロールと ChangePassword コントロールは、バックグラウンドでメンバーシップ フレームワークと連携して、ユーザーのパスワードをリセットまたは変更します。

このチュートリアルでは、これら 2 つのコントロールの使用について説明します。 また、MembershipUser クラスの ChangePasswordResetPassword メソッドを使用して、プログラムによってユーザーのパスワードを変更およびリセットする方法についても説明します。

手順 1: ユーザーが失われたパスワードを回復するのを支援する

ユーザー アカウントをサポートするすべての Web サイトでは、忘れたパスワードを回復するためのメカニズムをユーザーに提供する必要があります。 幸い、PasswordRecovery Web コントロールを使用すれば、ASP.NET でこのような機能を実装することは簡単です。 PasswordRecovery コントロールは、ユーザーにユーザー名の入力と、必要に応じてセキュリティの質問に対する回答を求めるインターフェイスをレンダリングします。 その後、パスワードをユーザーにメールで送信します。

Note

メール メッセージはプレーンテキストでネットワーク経由で送信されるため、メールでのパスワードの送信にはセキュリティ上のリスクが伴います。

PasswordRecovery コントロールは、次の 3 つのビューで構成されます。

  • UserName - 訪問者にユーザー名の入力を求めます。 これが最初のビューです。
  • Question - ユーザーのユーザー名とセキュリティの質問をテキストとして表示し、ユーザーがセキュリティの質問に対する回答を入力するための TextBox を表示します。
  • Success - パスワードがメールで送信されたことをユーザーに通知するメッセージを表示します。

PasswordRecovery コントロールによって表示されるビューと実行されるアクションは、次のメンバーシップ構成設定によって異なります。

  • RequiresQuestionAndAnswer
  • EnablePasswordRetrieval
  • EnablePasswordReset

メンバーシップ フレームワークの RequiresQuestionAndAnswer 設定は、ユーザーがアカウントに登録するときにセキュリティの質問と回答を指定する必要があるかどうかを示します。 ユーザー アカウントの作成のチュートリアルで説明したように、RequiresQuestionAndAnswer が True (既定値) の場合、CreateUserWizard のインターフェイスには、新しいユーザーのセキュリティの質問と回答の TextBox コントロールが含まれています。RequiresQuestionAndAnswer が False の場合、そのような情報は収集されません。 同様に、RequiresQuestionAndAnswer が True の場合、ユーザーがユーザー名を入力した後に PasswordRecovery コントロールに Question ビューが表示されます。パスワードは、ユーザーが正しいセキュリティ回答を入力した場合にのみ回復されます。 ただし、RequiresQuestionAndAnswer が False の場合、PasswordRecovery コントロールは UserName ビューから Success ビューに直接移動します。

ユーザーがユーザー名 (またはユーザー名とセキュリティの回答) を指定した後、RequiresQuestionAndAnswer が True の場合、PasswordRecovery はユーザーに自分のパスワードをメールで送信します。 EnablePasswordRetrieval オプションが True に設定されている場合、ユーザーには現在のパスワードがメールで送信されます。 これが False に設定され、EnablePasswordReset が True に設定されている場合、PasswordRecovery コントロールはユーザーに新しいランダムなパスワードを生成し、この新しいパスワードをメールで送信します。 EnablePasswordRetrievalEnablePasswordReset の両方とも False の場合、PasswordRecovery コントロールは例外をスローします。

Note

SqlMembershipProvider はユーザーのパスワードを、Clear、Hashed (既定)、Encrypted の 3 つの形式のいずれかで保存することを思い出してください。 使用されるストレージ メカニズムは、メンバーシップの構成設定によって異なります。デモ アプリケーションでは、Hashed のパスワード形式が使用されます。 Hashed のパスワード形式を使用する場合は、データベースに格納されているハッシュされたバージョンからユーザーの実際のパスワードをシステムが判断できないため、EnablePasswordRetrieval オプションを False に設定する必要があります。

図 1 は、PasswordRecovery のインターフェイスと動作がメンバーシップ構成によってどのように影響されるかを示しています。

The RequiresQuestionAndAnswer, EnablePasswordRetrieval, and EnablePasswordReset Influence the PasswordRecovery control's Appearance and Behavior

図 1: RequiresQuestionAndAnswerEnablePasswordRetrievalEnablePasswordReset が PasswordRecovery コントロールの外観と動作に影響を与える (選択するとフルサイズの画像が表示されます)

Note

SQL Server でメンバーシップ スキーマを作成する」のチュートリアルでは、RequiresQuestionAndAnswer を True、EnablePasswordRetrieval を False、EnablePasswordReset を True に設定してメンバーシップ プロバイダーを構成しました。

PasswordRecovery コントロールの使用

ASP.NET ページで PasswordRecovery コントロールを使用する方法を見てみましょう。 RecoverPassword.aspx を開き、ツールボックスからデザイナーに PasswordRecovery コントロールをドラッグ アンド ドロップします。その IDRecoverPwd に設定します。 Login や CreateUserWizard の Web コントロールと同様に、PasswordRecovery コントロールのビューは、ラベル、テキスト ボックス、ボタン、検証コントロールを含む高度な複合インターフェイスをレンダリングします。 コントロールのスタイル プロパティを使用するか、ビューをテンプレートに変換することで、ビューの外観をカスタマイズできます。 これは興味を持っている読者のための演習として残します。

このページにアクセスしたユーザーは、ユーザー名を入力し、[送信] ボタンを選択します。 メンバーシップ構成設定で RequiresQuestionAndAnswer プロパティを True に設定しているため、PasswordRecovery コントロールに Question ビューが表示されます。 ユーザーが正しいセキュリティの回答を入力して [送信] を選択すると、PasswordRecovery コントロールによって、ユーザーのパスワードがランダムに生成されたパスワードに更新され、ファイルのメール アドレスにこのパスワードがメールで送信されます。 これはすべて、コードを 1 行も記述せずに可能でした。

このページをテストする前に、構成の最後の部分として、Web.config でメール配信設定を指定する必要があります。 PasswordRecovery コントロールは、メールを送信するためにこれらの設定に依存します。

メール配信の構成は、<system.net> 要素<mailSettings> 要素を通じて指定されます。 <smtp> 要素を使用して、配信方法と既定の From アドレスを示します。 次のマークアップは、ポート 25 で smtp.example.com という名前のネットワーク SMTP サーバーを使用し、ユーザー名とパスワードの username/password 資格情報を使用するようにメール設定を構成します。

Note

<system.net> は、ルート <configuration> 要素の子要素であり、<system.web> の兄弟です。 そのため、<system.web> 要素内に <system.net> 要素を配置しないでください。代わりに、同じレベルに配置します。

<configuration>
 ...
 <system.net>
 <mailSettings>
 <smtp deliveryMethod="Network" from="youraddress@example.com">
 <network
 host="smtp.example.com"
 userName="username"
 password="password"
 port="25" />
 </smtp>
 </mailSettings>
 </system.net>
</configuration>

ネットワーク上の SMTP サーバーを使用するだけでなく、送信するメール メッセージを保存するピックアップ ディレクトリを指定することもできます。

SMTP 設定を構成したら、ブラウザーから RecoverPassword.aspx ページにアクセスします。 まず、ユーザー ストアに存在しないユーザー名を入力してみてください。 図 2 に示すように、PasswordRecovery コントロールには、ユーザー情報にアクセスできなかったことを示すメッセージが表示されます。 メッセージのテキストは、コントロールの UserNameFailureText プロパティを使用してカスタマイズできます。

An Error Message is Displayed if an Invalid Username is Entered

図 2: 無効なユーザー名が入力されるとエラー メッセージが表示される (選択するとフルサイズの画像が表示されます)

次に、ユーザー名を入力します。 アクセスできるメール アドレスを持ち、セキュリティに関する回答を把握している、システム内のアカウントのユーザー名を使用します。 ユーザー名を入力して [送信] を選択すると、PasswordRecovery コントロールに Question ビューが表示されます。 UserName ビューと同様に、正しくない回答を入力すると、PasswordRecovery コントロールにエラー メッセージが表示されます (図 3 を参照)。 QuestionFailureText プロパティを使用して、このエラー メッセージをカスタマイズします。

An Error Message is Displayed if the User Enters an Invalid Security Answer

図 3: ユーザーが無効なセキュリティ回答を入力すると、エラー メッセージが表示される (選択するとフルサイズの画像が表示されます)

最後に、正しいセキュリティ回答を入力し、[送信] を選択します。 バックグラウンドで PasswordRecovery コントロールは、ランダムなパスワードを生成し、それをユーザー アカウントに割り当て、ユーザーに新しいパスワードを通知するメールを送信して (図 4 を参照)、Success ビューを表示します。

The User is Sent an Email with His New Password

図 4: ユーザーが新しいパスワードでメールを送信する (選択するとフルサイズの画像が表示されます)

メールのカスタマイズ

PasswordRecovery コントロールによって送信される既定のメールでは、外観が配慮されていません (図 4 を参照)。 メッセージは、<smtp> 要素の from 属性で指定されたアカウントから、Password の件名でプレーン テキストの本文で送信されます。

サイトに戻り、次の情報を使用してログインしてください。

ユーザー名: username

パスワード: password

このメッセージは、PasswordRecovery コントロールの SendingMailイベントのイベント ハンドラーを使用してプログラムでカスタマイズすることも、MailDefinition プロパティを使用して宣言によってカスタマイズすることもできます。 これらのオプションの両方を調べてみましょう。

SendingMail イベントは、メール メッセージが送信される直前に発生し、プログラムによってメール メッセージを調整する最後の機会です。 このイベントが発生すると、イベント ハンドラーには、MailMessageEventArgs 型のオブジェクトが渡されます。その Message プロパティには、送信されるメールへの参照が含まれます。

SendingMail イベントのイベント ハンドラーを作成し、次のコードを追加します。このコードは、プログラムによって CC リストに webmaster@example.com を追加します。

protected void RecoverPwd_SendingMail(object sender, MailMessageEventArgs e)
{
    e.Message.CC.Add("webmaster@example.com");
}

メール メッセージは、宣言型の手段を使用して構成することもできます。 PasswordRecovery の MailDefinition プロパティは、MailDefinition 型のオブジェクトです。 MailDefinition クラスには、FromCCPrioritySubjectIsBodyHtmlBodyFileName など、メール関連のプロパティが多数用意されています。 まず、Subject プロパティを、既定で使用されているもの (Password) よりもわかりやすいものに設定します (Your password has been reset... など)。

メール メッセージの本文をカスタマイズするには、本文の内容を含む別のメール テンプレート ファイルを作成する必要があります。 まず、EmailTemplates という名前の Web サイトに新しいフォルダーを作成します。 次に、PasswordRecovery.txt という名前の新しいテキスト ファイルをこのフォルダーに追加し、次の内容を追加します。

Your password has been reset, <%UserName%>!

According to our records, you have requested that your password be reset. Your new
password is: <%Password%>

If you have any questions or trouble logging on please contact a site administrator.

Thank you!

プレースホルダーの <%UserName%><%Password%> の使用に注意してください。 PasswordRecovery コントロールは、メールを送信する前に、これら 2 つのプレースホルダーをユーザーのユーザー名と回復したパスワードに自動的に置き換えます。

最後に、MailDefinitionBodyFileName プロパティを先ほど作成したメール テンプレート (~/EmailTemplates/PasswordRecovery.txt) にポイントします。

これらの変更を行った後、RecoverPassword.aspx ページに再びアクセスし、ユーザー名とセキュリティの回答を入力します。 図 5 のようなメールが届きます。 webmaster@example.com が CC になっていて、件名と本文が更新されていることに注意してください。

The Subject, Body, and CC List Have Been Updated

図 5: 件名、本文、CC リストが更新されている (選択するとフルサイズの画像が表示されます)

HTML 形式のメールを送信するには、IsBodyHtml を True (既定値は False) に設定し、HTML を含めるようにメール テンプレートを更新します。

MailDefinition プロパティは PasswordRecovery クラスに固有ではありません。 手順 2 で説明するように、ChangePassword コントロールには MailDefinition プロパティも用意されています。 さらに、CreateUserWizard コントロールには、新しいユーザーにウェルカムメール メッセージを自動的に送信するように構成できるプロパティが含まれています。

Note

現在、左側のナビゲーションには、RecoverPassword.aspx ページにアクセスするためのリンクはありません。 ユーザーは、サイトに正常にログオンできなかった場合にのみ、このページにアクセスすることに関心があります。 そのため、Login.aspx ページを更新して、RecoverPassword.aspx ページへのリンクを含めます。

プログラムによるユーザーのパスワードのリセット

ユーザーのパスワードをリセットする場合、PasswordRecovery コントロールは、MembershipUser オブジェクトの ResetPassword メソッドを呼び出します。 このメソッドには 2 つのオーバーロードがあります。

  • ResetPassword - ユーザーのパスワードをリセットします。 RequiresQuestionAndAnswer が False の場合は、このオーバーロードを使用します。
  • ResetPassword(securityAnswer) - 指定された securityAnswer が正しい場合にのみ、ユーザーのパスワードをリセットします。 RequiresQuestionAndAnswer が True の場合は、このオーバーロードを使用します。

どちらのオーバーロードも、ランダムに生成された新しいパスワードを返します。

メンバーシップ フレームワークの他のメソッドと同様に、ResetPassword メソッドは構成されたプロバイダーに委任します。 SqlMembershipProvider は、aspnet_Membership_ResetPassword ストアド プロシージャを呼び出し、各フィールドの中から、ユーザーについて、ユーザー名、新しいパスワード、指定されたパスワードの回答を渡します。 ストアド プロシージャは、パスワードの応答が一致することを確認し、ユーザーのパスワードを更新します。

いくつかの低レベルの実装に関する注意事項:

  • ロックアウトされたユーザーは、自分のパスワードをリセットできません。 ただし、承認されていないユーザーには可能です。 ロックアウトされた状態と承認済みの状態については、「ユーザー アカウントをロック解除し、承認する」のチュートリアルで詳しく説明します。
  • パスワードの回答が正しくない場合、ユーザーの失敗したパスワード応答の試行回数が増分されます。 指定した期間内に、指定した数の無効なセキュリティ回答の試行が発生した場合、ユーザーはロックアウトされます。

ランダム パスワードの生成方法について

図 4 と図 5 のメール メッセージに示されているランダムに生成されたパスワードは、Membership クラスの GeneratePassword メソッドによって作成されます。 このメソッドは、2 つの整数入力パラメーター (lengthnumberOfNonAlphanumericCharacters) を受け取り、length 文字以上の長さで、英数字以外の文字の数が numberOfNonAlphanumericCharacters 文字以上の文字列を返します。 このメソッドが Membership クラスまたはログイン関連 Web コントロール内から呼び出されると、これら 2 つのパラメーターの値は、メンバーシップ構成の MinRequiredPasswordLength プロパティと MinRequiredNonalphanumericCharacters プロパティによって決まります。このプロパティはそれぞれ 7 と 1 に設定します。

GeneratePassword メソッドでは、選択されるランダムな文字に偏りがないようにするために、暗号強度の高い乱数ジェネレーターが使用されます。 さらに、GeneratePasswordpublic です。つまり、ランダムな文字列またはパスワードを生成する必要がある場合は、ASP.NET アプリケーションから直接使用できることを意味します。

Note

SqlMembershipProvider クラスでは、常に 14 文字以上のランダムなパスワードが生成されるため、MinRequiredPasswordLength が 14 文字未満の場合、その値は無視されます。

手順 2: パスワードを変更する

ランダムに生成されたパスワードは簡単には覚えられません。 図 4 に示されているパスワード WWGUZv(f2yM:Bd について考えてみましょう。 メモリにコミットしてみてください。 言うまでもなく、この種のランダムに生成されたパスワードを受け取ったユーザーは、より覚えやすいパスワードに変更したくなります。

ChangePassword コントロールを使用して、ユーザーがパスワードを変更するためのインターフェイスを作成します。 PasswordRecovery コントロールと同様に、ChangePassword コントロールは、Change Password と Success という 2 つのビューで構成されます。 Change Password ビューでは、ユーザーは、古いパスワードと新しいパスワードの入力を求められます。 正しい古いパスワードと、最小文字数と英数字以外の文字数の要件を満たす新しいパスワードを指定すると、ChangePassword コントロールはユーザーのパスワードを更新し、Success ビューを表示します。

Note

ChangePassword コントロールは、MembershipUser オブジェクトの ChangePassword メソッドを呼び出すことによって、ユーザーのパスワードを変更します。 ChangePassword メソッドは、2 つの string 入力パラメーター (oldPasswordnewPassword) を受け取り、指定された oldPassword が正しいと仮定して、newPassword を使用してユーザーのアカウントを更新します。

ChangePassword.aspx ページを開き、ChangePassword コントロールをページに追加して、ChangePwd と名前を付けます。 この時点で、デザイン ビューに Change Password ビューが表示されます (図 6 を参照)。 PasswordRecovery コントロールと同様に、コントロールのスマート タグを使用してビューを切り替えることができます。 さらに、これらのビューの外観は、各種のスタイル プロパティを使用するか、テンプレートに変換することでカスタマイズできます。

Add a ChangePassword Control to the Page

図 6: ChangePassword コントロールをページに追加する (選択するとフルサイズの画像が表示されます)

ChangePassword コントロールは、現在ログインしているユーザーのパスワードまたは別の指定されたユーザーのパスワードを更新できます。 図 6 に示すように、既定の Change Password ビューには、古いパスワード用に 1 つと、新しいパスワード用に 2 つの、3 つの TextBox コントロールだけが表示されます。 この既定のインターフェイスは、現在ログオンしているユーザーのパスワードを更新するために使用されます。

ChangePassword コントロールを使用して別のユーザーのパスワードを更新するには、コントロールの DisplayUserName プロパティを True に設定します。 これにより、4 番目の TextBox がページに追加され、パスワードを変更するユーザーのユーザー名の入力を求められます。

DisplayUserName を True に設定すると、ログアウトしたユーザーが、ログインしなくても自分のパスワードを変更できるようにする場合に便利です。 個人的には、パスワードの変更を許可する前にユーザーにログインを要求することに問題はないと思います。 したがって、DisplayUserName は False (既定値) に設定したままにします。 ただし、この決定を行う際には、基本的に匿名ユーザーがこのページにアクセスできないようにしています。 匿名ユーザーが ChangePassword.aspx にアクセスするのを拒否するように、サイトの URL 承認規則を更新します。 URL 承認規則の構文でメモリを更新する必要がある場合は、「ユーザー ベースの承認」のチュートリアルを参照してください。

Note

DisplayUserName プロパティは、管理者が他のユーザーのパスワードを変更できるようにするために役立つと思われる場合があります。 しかし、DisplayUserName が True に設定されている場合でも、正しい古いパスワードを認識して入力する必要があります。 手順 3 で管理者がユーザーのパスワードを変更できるようにする手法について説明します。

ブラウザーから ChangePassword.aspx ページにアクセスし、パスワードを変更します。 メンバーシップ構成で指定されているパスワードの長さと、英数字以外の文字の要件を満たしていない新しいパスワードを入力すると、エラー メッセージが表示されることに注意してください (図 7 を参照)。

An error message is displayed if you enter a new password that fails to meet the password length and non-alphanumeric character requirements.

図 7: ChangePassword コントロールをページに追加する (選択するとフルサイズの画像が表示されます)

正しい古いパスワードと有効な新しいパスワードを入力すると、ログオンしているユーザーのパスワードが変更され、Success ビューが表示されます。

確認メールの送信

既定では、ChangePassword コントロールは、パスワードを更新したばかりのユーザーにメール メッセージを送信しません。 メールを送信する場合は、コントロールの MailDefinition プロパティを構成するだけです。 新しいパスワードを含む HTML 形式のメールがユーザーに送信されるように ChangePassword コントロールを構成してみましょう。

まず、ChangePassword.htm という名前の EmailTemplates フォルダーに新しいファイルを作成します。 次のマークアップを追加します。

<html>
 <body>
 <h2>Your Password Has Been Changed!</h2>
 <p>
 This email confirms that your password has been changed.
 </p>
 <p>
 To log on to the site, use the following credentials:
 </p>
 <table>
 <tr>
 <td>
 <b>Username:</b>
 </td>
 <td>
 <%UserName%>
 </td>
 </tr>
 <tr>
 <td>
 <b>Password:</b>
 </td>
 <td>
 <%Password%>
 </td>
 </tr>
 </table>
 <p>
 If you have any questions or encounter any problems logging in,
 please contact a site administrator.
 </p>
 </body>
</html>

次に、ChangePassword コントロールの MailDefinition プロパティの BodyFileNameIsBodyHtml、および Subject プロパティを ~/EmailTemplates/ChangePassword.htm、True、および Your password has changed! にそれぞれ設定します。

これらの変更を行った後、ページに再びアクセスし、パスワードをもう一度変更します。 今回は、ChangePassword コントロールによって、カスタマイズされた HTML 形式のメールがファイル上のユーザーのメール アドレスに送信されます (図 8 を参照)。

An Email Message Informs the User That Their Password has Changed

図 8: パスワードが変更されたことをメール メッセージユーザーに通知する (選択するとフルサイズの画像が表示されます)

手順 3: 管理者がユーザーのパスワードを変更できるようにする

ユーザー アカウントをサポートするアプリケーションの一般的な機能として、管理ユーザーが他のユーザーのパスワードを変更できます。 ユーザーが自分のパスワードを変更するための機能がシステムにないために、この機能が必要になる場合があります。 このような場合、ユーザーが忘れたパスワードを回復する唯一の方法は、管理者が新しいパスワードを割り当てることです。 ただし、PasswordRecovery コントロールと ChangePassword コントロールを使用すると、ユーザーは自分でパスワードを変更できるため、管理ユーザーがユーザー パスワードの変更に忙しくする必要はありません。

しかし、管理ユーザーが他のユーザーのパスワードを変更できるようにする必要があるとクライアントが主張した場合はどうでしょうか。 残念ながら、この機能の追加する作業には、少し手間がかかるかもしれません。 ユーザーのパスワードを変更するには、MembershipUser オブジェクトの ChangePassword メソッドに古いパスワードと新しいパスワードの両方を指定する必要がありますが、管理者がユーザーのパスワード変更するためにそれを知っているはずはありません。

回避策の 1 つは、次のようなコードを使用して、最初にユーザーのパスワードをリセットしてから、新しいパスワードに変更することです。

MembershipUser usr = Membership.GetUser(username);
string resetPwd = usr.ResetPassword();
usr.ChangePassword(resetPwd, newPassword);

このコードは、まず、管理者がパスワードを変更するユーザーである username に関する情報を取得することから始めます。 次に、ResetPassword メソッドが呼び出され、ユーザーに新しいランダムなパスワードが割り当てられます。 このランダムに生成されたパスワードは、メソッドによって返され、変数 resetPwd に格納されます。 ユーザーのパスワードがわかったので、ChangePassword への呼び出しで変更できます。

問題は、このコードは、メンバーシップ システム構成が、RequiresQuestionAndAnswer が False になるように設定されている場合にのみ機能します。 RequiresQuestionAndAnswer が True の場合は、今回のアプリケーションと同様に、ResetPassword メソッドにセキュリティの回答を渡す必要があります。そうしないと、例外がスローされます。

メンバーシップ フレームワークがセキュリティの質問と回答を要求するように構成されていても、管理者がユーザーのパスワードを変更できることをクライアントが要求する場合には、次の 3 つのオプションがあります。

  • 両手を振り上げて、これだけはできないとクライアントに伝えます。
  • RequiresQuestionAndAnswer を False に設定します。 これにより、アプリケーションの安全性が低下します。 悪質なユーザーが別のユーザーのメール受信トレイにアクセスしたとします。 おそらく、侵害されたユーザーは、ランチに行くために机を離れてワークステーションをロックしなかったか、パブリック ターミナルからメールにアクセスしてサインアウトしなかった可能性があります。どちらの場合も、悪質なユーザーは RecoverPassword.aspx ページにアクセスし、ユーザーのユーザー名を入力できます。 その後、システムは、セキュリティの回答を求めることなく、回復したパスワードをメールで送信します。
  • メンバーシップ フレームワークによって作成された抽象化レイヤーをバイパスし、SQL Server データベースを直接操作します。 メンバーシップ スキーマには、ユーザーのパスワードを設定する aspnet_Membership_SetPassword という名前のストアド プロシージャが含まれており、そのタスクを実行するためにセキュリティの回答や古いパスワードは必要ありません。

これらのオプションのいずれも特に魅力的ではありませんが、開発者の生活にはたまにある話です。

ここでは、3 番目のアプローチを実装して、Membership クラスと MembershipUser クラスをバイパスし、SecurityTutorials データベースを直接操作するコードを記述しました。

Note

データベースを直接操作すると、メンバーシップ フレームワークによって提供されるカプセル化が損なわれます。 この決定により SqlMembershipProvider を使用することになり、コードの移植性が低下します。 さらに、メンバーシップ スキーマが変更された場合、このコードは将来のバージョンの ASP.NET で期待どおりに動作しない可能性があります。 この方法は回避策であり、ほとんどの回避策と同様に、ベスト プラクティスの例ではありません。

コードには魅力的でないビットがいくつかあり、非常に長くなっています。 そのため、ここで詳細に調査して、このチュートリアルをわかりにくくしたくありません。 さらに学習したい場合は、このチュートリアルのコードをダウンロードして ~/Administration/ManageUsers.aspx のページにアクセスしてください。 前のチュートリアルで作成したこのページには、各ユーザーが一覧表示されます。 UserInformation.aspx ページへのリンクを含むように GridView を更新し、選択したユーザーのユーザー名をクエリ文字列を通じて渡しました。 UserInformation.aspx ページには、選択したユーザーに関する情報と、パスワードを変更するための TextBox が表示されます (図 9 を参照)。

新しいパスワードを入力し、2 番目の TextBox でそれを確認し、[Update User] ボタンを選択すると、ポストバックが実行され、aspnet_Membership_SetPassword ストアド プロシージャが呼び出され、ユーザーのパスワードが更新されます。 この機能に関心がある方に、コードをよりよく理解し、パスワードが変更されたユーザーへのメールの送信を含めるように機能を拡張してみることをお勧めします。

An Administrator May Change a User's Password

図 9: 管理者がユーザーのパスワードを変更できる (クリックするとフルサイズの画像が表示されます)

Note

現在、UserInformation.aspx ページは、パスワードを Clear または Hashed 形式で格納するようにメンバーシップ フレームワークが構成されている場合にのみ機能します。 この機能を追加するように勧められていますが、新しいパスワードを暗号化するコードがありません。 必要なコードを追加するのにお勧めする方法は、Reflector のような逆コンパイラを使用して、.NET Framework 内のメソッドのソース コードを調べることです。まず、SqlMembershipProvider クラスの ChangePassword メソッドを調べます。 これは、パスワードのハッシュを作成するためのコードを記述するための手法です。

まとめ

ASP.NET には、ユーザーが自分のパスワードを管理するのに役立つ 2 つのコントロールが用意されています。 PasswordRecovery コントロールは、パスワードを忘れたユーザーに役立ちます。 メンバーシップ フレームワークの構成に応じて、ユーザーは既存のパスワードまたはランダムに生成された新しいパスワードをメールで送信されます。 ChangePassword コントロールを使用すると、ユーザーは自分のパスワードを更新できます。

Login コントロールや CreateUserWizard コントロールと同様に、PasswordRecovery コントロールと ChangePassword コントロールは、宣言型マークアップやコード行を少しも記述することなく、リッチなユーザー インターフェイスをレンダリングします。 既定のユーザー インターフェイスがニーズを満たしていない場合は、さまざまなスタイル プロパティを使用してカスタマイズできます。 あるいは、コントロールのインターフェイスをテンプレートに変換して、さらに細かい制御を行うこともできます。 これらのコントロールはバックグラウンドで Membership API を使用し、MembershipUser オブジェクトの ResetPassword メソッドと ChangePassword メソッドを呼び出します。

プログラミングに満足!

もっと読む

この記事で説明したトピックの詳細については、次のリソースを参照してください。

作成者について

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

特別な感謝

このチュートリアル シリーズは、多くの役に立つ校閲者によってレビューされました。 Michael Emmings と Suchi Banerjee は、このチュートリアルのリード レビュー担当者の一員です。 今後の MSDN の記事を確認することに関心がありますか? ご希望の場合は、mitchell@4GuysFromRolla.com 宛にメールをお送りください