フォーム認証の概要 (VB)

作成者: Scott Mitchell

Note

この記事の作成時以降に、ASP.NET メンバーシップ プロバイダーは ASP.NET Identity に置き換えられています。 アプリを更新し、この記事の作成時点で紹介したメンバーシップ プロバイダーではなく、ASP.NET Identity プラットフォームを使用することを強く推奨します。 ASP.NET メンバーシップ システムと比較すると、ASP.NET ID には以下を含む多くの利点があります。

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

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

このチュートリアルでは、まずフォーム認証の概要を説明し、実装に移ります。特にフォーム認証の実装を詳細に取り上げます。 このチュートリアルで構築し始める Web アプリケーションは、まず単純なフォーム認証を作成し、後続のチュートリアルでメンバーシップとロールまで構築を進めていきます。

このトピックの詳細については、このビデオを参照してください: ASP.NET で基本フォーム認証を使用する

はじめに

前のチュートリアルでは、ASP.NET によって提供されるさまざまな認証、承認、およびユーザー アカウントのオプションについて説明しました。 このチュートリアルでは、まずフォーム認証の概要を説明し、実装に移ります。特にフォーム認証の実装を詳細に取り上げます。 このチュートリアルで構築し始める Web アプリケーションは、まず単純なフォーム認証を作成し、後続のチュートリアルでメンバーシップとロールまで構築を進めていきます。

このチュートリアルでは、前のチュートリアルで言及したトピックであるフォーム認証ワークフローについて詳しく説明します。 その後、フォーム認証の概念をデモする ASP.NET Web サイトを作成します。 次に、フォーム認証を使用するようにサイトを構成し、簡単なログイン ページを作成し、ユーザーが認証されているかどうかをコードで確認する方法と、認証されている場合、ユーザーがログインに使用したユーザー名を確認する方法を説明します。

フォーム認証ワークフローを理解し、Web アプリケーションで有効にし、ログイン ページとログオフ ページを作成することは、ユーザー アカウントをサポートし、Web ページを介してユーザーを認証する ASP.NET アプリケーションを構築する上で重要な手順です。 このことと、これらのチュートリアルが前段を踏まえて構築されている理由により、過去のプロジェクトでフォーム認証の構成を既に経験している場合でも、次のチュートリアルに進む前に、このチュートリアルを一通り実行することをお勧めします。

フォーム認証ワークフローについて

ASP.NET ランタイムが ASP.NET ページや ASP.NET Web サービスなどの ASP.NET リソースの要求を処理するときに、その要求は、ライフサイクル中に多数のイベントを発生させます。 これらには、要求の最初と最後に発生するイベント、要求が認証および承認されるときに発生するイベント、ハンドルされない例外時に発生するイベントなどがあります。 イベントの完全な一覧を表示するには、HttpApplication オブジェクトのイベントを参照してください。

HTTP モジュールは、要求ライフサイクル内の特定のイベントに応答してコードが実行されるマネージド クラスです。 ASP.NET には、バックグラウンドで重要なタスクを実行する多数の HTTP モジュールが付属しています。 ここでのディスカッションに特に関連する 2 つの組み込み HTTP モジュールは次のとおりです。

  • FormsAuthenticationModule - フォーム認証チケットを調べることでユーザーを認証します。通常このチケットは、ユーザーの Cookie コレクションに含まれています。 フォーム認証チケットが存在しない場合、ユーザーは匿名になります。
  • UrlAuthorizationModule - 現在のユーザーが要求された URL へのアクセスを許可されているかどうかを判定します。 このモジュールでは、アプリケーションの構成ファイルで指定された認可規則を調べて、権限を決定します。 ASP.NET には、要求されたファイル ACL を参照して権限を決定する FileAuthorizationModule も含まれています。

FormsAuthenticationModule は、UrlAuthorizationModule (および FileAuthorizationModule) が実行される前に、ユーザーの認証を試みます。 要求を行っているユーザーが、要求されたリソースへのアクセスを許可されていない場合、承認モジュールは要求を終了し、HTTP 401 認可されていない状態を返します。 Windows 認証シナリオでは、HTTP 401 状態がブラウザーに返されます。 この状態コードにより、ブラウザーはモーダル ダイアログ ボックスを使用してユーザーに資格情報の入力を求めます。 ただし、フォーム認証では、FormsAuthenticationModule がこの状態を検出し、代わりに HTTP 302 リダイレクト状態を介してログイン ページにユーザーをリダイレクトするように変更するため、「HTTP 401 認可されていない」状態はブラウザーに送信されません。

ログイン ページの役割は、ユーザーの資格情報が有効かどうかを判断し、有効な場合はフォーム認証チケットを作成し、ユーザーがアクセスを試みていたページにユーザーをリダイレクトすることです。 認証チケットは、Web サイト上のページに対する後続の要求に含められます。この要求は、FormsAuthenticationModule がユーザーを識別するために使用されます。

The Forms Authentication Workflow

図 01: フォーム認証ワークフロー (フルサイズ画像を表示するにはこちらをクリックしてください)

ページ アクセス間での認証チケットの記憶

ログイン後、このフォーム認証チケットは、ユーザーがサイトをブラウズする間ログインしたままになるように、各要求時に Web サーバーに返送される必要があります。 これは通常、ユーザーの Cookie コレクションに認証チケットを配置することによって実現されます。 Cookie とは、ユーザーのコンピューター上に存在し、各要求の HTTP ヘッダーで Cookie を作成した Web サイトに送信される小さなテキスト ファイルです。 そのため、フォーム認証チケットが作成され、ブラウザーの Cookie に格納されると、そのサイトにアクセスするたびに、要求と共に認証チケットが送信され、ユーザーが識別されます。

Note

各チュートリアルで使用されるデモ Web アプリケーションは、ダウンロードとして入手できます。 このダウンロード可能なアプリケーションは、.NET Framework バージョン 3.5 を対象とする Visual Web Developer 2008 で作成されました。 このアプリケーションは .NET 3.5 を対象としているため、その Web.config ファイルには、追加の 3.5 固有の構成要素が含まれています。 簡単に言うと、コンピューターに .NET 3.5 をまだインストールしていない場合、このダウンロード可能な Web アプリケーションは、先に Web.config から 3.5 固有のマークアップを削除しないと機能しません。

Cookie の 1 つの側面は、その有効期限にあります。これは、ブラウザーが Cookie を破棄する日時です。 フォーム認証 Cookie の有効期限が切れると、ユーザーは認証されなくなるため、その結果匿名になります。 あるユーザーが公共のターミナルからアクセスする場合、ブラウザーを閉じるときに、認証チケットの有効期限が切れるようにしたいとします。 しかし、その同じユーザーは、自宅からアクセスする場合には、サイトにアクセスするたびに再ログインする必要がないように、ブラウザーの再起動時に認証チケットを記憶したいと考えます。 この決定は、多くの場合にユーザーによって行われ、ログイン ページの [Remember me]\(サインイン情報を記憶\) チェックボックスの形で実行されます。 手順 3 では、ログイン ページで [Remember me]\(サインイン情報を記憶\) チェックボックスを実装する方法を確認します。 次のチュートリアルでは、認証チケットのタイムアウト設定について詳しく説明します。

Note

Web サイトへのログオンに使用したユーザー エージェントが、Cookie をサポートしていない可能性があります。 このような場合、ASP.NET は、Cookie なしのフォーム認証チケットを使用できます。 このモードでは、認証チケットは URL にエンコードされます。 次のチュートリアルでは、Cookie なしの認証チケットがいつ使用され、どのように作成および管理されるかを確認します。

フォーム認証のスコープ

FormsAuthenticationModule は、ASP.NET ランタイムの一部であるマネージド コードです。 Microsoft のインターネット インフォメーション サービス (IIS) Web サーバーのバージョン 7 より前のバージョンは、IIS の HTTP パイプラインと ASP.NET ランタイムのパイプラインとの間に明確な障壁がありました。 つまり、IIS 6 以前では、FormsAuthenticationModule は、要求が IIS から ASP.NET ランタイムに委任されたときにのみ実行されます。 既定では、IIS は静的コンテンツ自体 (HTML ページ、CSS、イメージ ファイルなど) を処理し、.aspx、.asmx、または .ashx の拡張子を持つページが要求されたときにのみ、ASP.NET ランタイムに要求を渡します。

ただし、IIS 7 では、統合された IIS パイプラインと ASP.NET パイプラインを使用できます。 いくつかの構成設定によって、すべての要求に対して FormsAuthenticationModule を呼び出せるように IIS 7 を設定することが可能です。 さらに、IIS 7 では、任意の種類のファイルの URL 認可規則を定義できます。 詳細については、「IIS6 と IIS7 セキュリティの間の変更」、「Web プラットフォームのセキュリティ」、「IIS7 URL 承認について」を参照してください。

簡単に言うと、IIS 7 より前のバージョンでは、フォーム認証のみを使用して、ASP.NET ランタイムによって処理されるリソースを保護できます。 同様に、URL 認可規則は、ASP.NET ランタイムによって処理されるリソースにのみ適用されます。 ただし、IIS 7 では、FormsAuthenticationModule と UrlAuthorizationModule を IIS の HTTP パイプラインに統合できるため、この機能をすべての要求に拡張できます。

手順 1: このチュートリアル シリーズの ASP.NET Web サイトの作成

可能な限り幅広い対象ユーザーにご利用いただくために、このシリーズ全体を通して構築する ASP.NET Web サイトは、Microsoft の無料バージョンの Visual Studio 2008 である Visual Web Developer 2008 で作成されます。 Microsoft SQL Server 2005 Express Edition データベースに SqlMembershipProvider ユーザー ストアを実装します。 Visual Studio 2005、または Visual Studio 2008 か SQL Server の別のエディションを使用している場合も、手順はほぼ同じのため、心配は要りません。些細でない違いがある場合は、そのように指摘されます。

フォーム認証を構成する前に、まず ASP.NET Web サイトが必要です。 まず、新しいファイル システム ベースの ASP.NET Web サイトを作成します。 これを行うには、Visual Web Developer を起動し、[ファイル] メニューに移動し、[新しい Web サイト] を選択し、[新しい Web サイト] ダイアログ ボックスを表示します。 ASP.NET Web サイト テンプレートを選択し、[場所] ドロップダウン リストを [ファイル システム] に設定し、Web サイトを配置するフォルダーを選択して、言語を VB に設定します。 これにより、Default.aspx ASP.NET ページ、App_Data フォルダー、Web.config ファイルを含む新しい Web サイトが作成されます。

Note

Visual Studio では、Web サイト プロジェクトと Web アプリケーション プロジェクトの 2 つのモードのプロジェクト管理がサポートされています。 Web サイト プロジェクトにはプロジェクト ファイルがありませんが、Web アプリケーション プロジェクトは Visual Studio .NET 2002/2003 のプロジェクト アーキテクチャを模倣します。これらにはプロジェクト ファイルが含まれ、プロジェクトのソース コードを 1 つのアセンブリにコンパイルし、/bin フォルダーに配置します。 Visual Studio 2005 では、最初は Web サイト プロジェクトのみがサポートされていましたが、Web アプリケーション プロジェクト モデルが Service Pack 1 で再導入されました。Visual Studio 2008 には、両方のプロジェクト モデルが用意されています。 ただし、Visual Web Developer 2005 および 2008 エディションでは、Web サイト プロジェクトのみがサポートされます。 ここでは Web サイト プロジェクト モデルを使用します。 Express 以外のエディションを使用していて、代わりに Web アプリケーション プロジェクト モデルを使用する場合は、自由にそうできますが、画面に表示される内容と実行する必要がある手順と、これらのチュートリアルで提供されている手順とは一致しない場合があることに注意してください。

Create a New File System-Based Web Site

図 02: 新しいファイル システムベースの Web サイトを作成します (クリックするとフルサイズの画像が表示されます)

マスター ページの追加

次に、Site.master という名前のルート ディレクトリ内のサイトに新しいマスター ページを追加します。 マスター ページを使用すると、ページ開発者は、ASP.NET ページに適用できるサイト全体のテンプレートを定義できます。 マスター ページを設ける主な利点は、サイトの全体的な外観を 1 つの場所で定義できるため、サイトのレイアウトを簡単に更新または調整できることにあります。

Add a Master Page Named Site.master to the Website

図 03: Web サイトに Site.master という名前のマスター ページを追加する (フルサイズ画像を表示するにはこちらをクリックしてください)

サイト全体のページ レイアウトは、このマスター ページ内で定義します。 デザイン ビューを使用して、必要なレイアウト コントロールや Web コントロールを追加したり、ソース ビューで手動でマークアップを追加したりできます。 「ASP.NET 2.0 でのデータの操作」チュートリアル シリーズで使用したレイアウトを模倣したマスター ページのレイアウトを構造化しました (図 4 を参照)。 このマスター ページでは、Style.css ファイル (このチュートリアルの関連ダウンロードに含まれている) で定義されている CSS 設定を使用して、配置とスタイルにカスケード スタイル シートを使用します。 以下に示すマークアップからは見分けられませんが、CSS ルールは、ナビゲーション <div> のコンテンツが絶対値で配置され、左側に表示され、固定幅が 200 ピクセルになるように定義されています。

<%@ Master Language="VB" CodeFile="Site.master.vb" Inherits="Site" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
 <head id="Head1" runat="server">
 <title>Forms Authentication, Authorization, and User Accounts</title>
 <link href="Styles.css" rel="stylesheet" type="text/css" />
 </head>
 <body>
 <div id="wrapper">
 <form id="form1" runat="server">
 <div id="header">
 <span class="title">User Account Tutorials</span>
 </div>
 <div id="content">
 <asp:contentplaceholder id="MainContent" runat="server">
 <!-- Page-specific content will go here... -->
 </asp:contentplaceholder>
 </div>
 <div id="navigation">
 TODO: Menu will go here...
 </div>
 </form>
 </div>
 </body>
</html>

マスター ページは、静的なページ レイアウトとそのマスター ページを使用する ASP.NET ページによって編集可能な領域の両方を定義します。 これらのコンテンツ編集可能な領域は、ContentPlaceHolder コントロールによって示され、コンテンツ <div> 内で表示できます。 このマスター ページが持つ ContentPlaceHolder (MainContent) は 1 つですが、マスター ページは複数の ContentPlaceHolder を持つことができます。

上記のマークアップを入力すると、デザイン ビューへの切り替えによってマスター ページのレイアウトが表示されます。 このマスター ページを使用するすべての ASP.NET ページが、この統一されたレイアウトと、MainContent 領域のマークアップを指定するための機能を持つことになります。

The Master Page, When Viewed Through the Design View

図 04: デザイン ビューを通して表示されたマスター ページ (フルサイズ画像を表示するにはこちらをクリックしてください)

コンテンツ ページの作成

この時点で、Web サイトに Default.aspx ページがありますが、作成したマスター ページは使用されていません。 Web ページの宣言型マークアップを操作してマスター ページを使用することもできますが、ページにコンテンツがまだ含まれていない場合は、ページをただ削除してプロジェクトに再追加し、使用するマスター ページを指定する方が簡単です。 そのため、まずプロジェクトから Default.aspx を削除します。

次に、ソリューション エクスプローラーでプロジェクト名を右クリックし、Default.aspx という名前の新しい Web フォームを追加することを選択します。 今回は、[マスター ページの選択] チェック ボックスをオンにし、一覧から Site.master マスター ページを選択します。

Add a New Default.aspx Page Choosing to Select a Master Page

図 05: [マスター ページの選択] を選択して新しい Default.aspx ページを追加する (フルサイズ画像を表示するにはこちらをクリックしてください)

Use the Site.master Master Page

図 06: Site.master マスター ページを使用する (フルサイズ画像を表示するにはこちらをクリックしてください)

Note

Web アプリケーション プロジェクト モデルを使用している場合、[新しいアイテムの追加] ダイアログ ボックスに [マスター ページの選択] チェック ボックスは含まれません。 代わりに、Web コンテンツ フォームの種類の項目を追加する必要があります。 [Web コンテンツ フォーム] オプションを選択して [追加] をクリックすると、図 6 に示すのと同じ [マスター ページの選択] ダイアログ ボックスが Visual Studio に表示されます。

新しい Default.aspx ページの宣言型マークアップには、マスター ページ ファイルへのパスを指定する @Page ディレクティブと、マスター ページの MainContent ContentPlaceHolder の Content コントロールのみが含まれます。

<%@ Page Language="VB" MasterPageFile="~/Site.master" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" Title="Untitled Page" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" Runat="Server">
</asp:Content>

ここでは、Default.aspx を空のままにします。 このチュートリアルの後半でこれに戻り、コンテンツを追加します。

Note

マスター ページには、メニューまたはその他のナビゲーション インターフェイスのセクションが含まれています。 このようなインターフェイスは、今後のチュートリアルで作成します。

手順 2: フォーム認証の有効化

ASP.NET Web サイトを作成したら、次のタスクはフォーム認証を有効にすることです。 アプリケーションの認証構成は、Web.config の <認証> 要素を使用して指定されます。<authentication> 要素には、アプリケーションで使用される認証モデルを指定する mode という名前の 1 つの属性が含まれています。 この属性には、次の 4 つの値のいずれかを指定できます。

  • Windows - 前のチュートリアルで説明したように、アプリケーションが Windows 認証を使用する場合、訪問者を認証するのは Web サーバーの責任であり、これは通常、基本認証、ダイジェスト認証、または統合 Windows 認証によって行われます。
  • Forms - ユーザーは Web ページ上のフォームを介して認証されます。
  • Passport- ユーザーは Microsoft Passport Network を使用して認証されます。
  • None- 認証モデルは使用されません。すべての訪問者は匿名です。

既定では、ASP.NET アプリケーションは Windows 認証を使用します。 認証の種類をフォーム認証に変更するには、<authentication> 要素の mode 属性を Forms に変更する必要があります。

プロジェクトに Web.config ファイルがまだ含まれていない場合は、ソリューション エクスプローラーでプロジェクト名を右クリックし、[新しいアイテムの追加] を選択し、Web 構成ファイルを追加して追加します。

If Your Project Does Not Yet Include Web.config, Add It Now

図 07: プロジェクトに Web.config がまだ含まれていない場合は、[今すぐ追加] をクリックします (フルサイズ画像を表示するにはこちらをクリックしてください)

次に、<authentication> 要素を見つけて、フォーム認証を使用するように更新します。 この変更後、Web.config ファイルのマークアップは次のようになります。

<configuration>
 <system.web>
 ... Unrelated configuration settings and comments removed for brevity ...
 <!--
 The <authentication> section enables configuration 
 of the security authentication mode used by 
 ASP.NET to identify an incoming user. 
 -->
 <authentication mode="Forms" />
 </system.web>
</configuration>

Note

Web.config は XML ファイルであるため、大文字と小文字を区別するのが重要です。 モード属性は、必ず大文字の F を使った Forms に設定します。forms など大文字と小文字の区別が異なると、ブラウザーからサイトにアクセスするときに構成エラーが発生します。

<認証> 要素には、必要に応じて、フォーム認証固有の設定を含む <フォーム> 子要素を含めることができます。 ここでは、既定のフォーム認証設定を使用するままにします。 次のチュートリアルでは、<forms> の子要素について詳しく説明します。

手順 3: ログイン ページの構築

フォーム認証をサポートするには、Web サイトにログイン ページが必要です。 「フォーム認証ワークフローについて」セクションで説明したように、FormsAuthenticationModule は、表示が許可されていないページにアクセスしようとすると、ユーザーをログイン ページに自動的にリダイレクトします。 匿名ユーザーに対してログイン ページへのリンクを表示する ASP.NET Web コントロールもあります。 ここで疑問が生じるのは、ログイン ページの URL は何かということです。

フォーム認証システムの既定では、ログイン ページに Login.aspx という名前が付けられ、Web アプリケーションのルート ディレクトリに配置されます。 別のログイン ページ URL を使用する場合は、Web.config でそのページを指定することで実行できます。これを行う方法については、以降のチュートリアルで説明します。

ログイン ページには、次の 3 つの役割があります。

  1. 訪問者が自分の資格情報を入力できるようにするインターフェイスを指定します。
  2. 送信された資格情報が有効かどうかを判断します。
  3. フォーム認証チケットを作成してユーザーをログインさせます。

ログイン ページのユーザー インターフェイスの作成

それでは、最初のタスクを開始しましょう。 新しい ASP.NET ページを Login.aspx という名前のサイトのルート ディレクトリに追加し、Site.master マスター ページに関連付けます。

Add a New ASP.NET Page Named Login.aspx

図 08: Login.aspx という名前の新しい ASP.NET ページを追加します (フルサイズ画像を表示するにはこちらをクリックしてください)

一般的なログイン ページ インターフェイスは、2 つのテキスト ボックス (1 つはユーザー名用、もう 1 つはパスワード用) とフォームを送信するためのボタンで構成されています。 Web サイトには、多くの場合、[Remember me]\(サインイン情報を記憶\) チェック ボックスが表示されます。チェック ボックスをオンにすると、ブラウザーの再起動後も結果の認証チケットが保持されます。

2 つの TextBox を Login.aspx に追加し、ID プロパティをそれぞれ UserName と Password に設定します。 また、Password の TextMode プロパティを Password に設定します。 次に、CheckBox コントロールを追加し、ID プロパティを RememberMe に設定し、Text プロパティを Remember Me に設定します。 次に、Text プロパティを Login に設定した LoginButton という名前のボタンを追加します。 最後に、Label Web コントロールを追加し、その ID プロパティを InvalidCredentialsMessage に設定します。この Text プロパティを "Your username or password is invalid. Please try again." に設定し、ForeColor プロパティを Red に、Visible プロパティを False に設定します。

この時点で、画面は図 9 のスクリーン ショットのようになります。ページの宣言型構文は次のようになります。

<%@ Page Language="VB" MasterPageFile="~/Site.master" AutoEventWireup="false" CodeFile="Login.aspx.vb" Inherits="Login" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" Runat="Server">
 <h1>
 Login
 </h1>
 <p>
 Username: <asp:TextBox ID="UserName" runat="server"></asp:TextBox>
 </p>
 <p>
 Password: <asp:TextBox ID="Password" runat="server" TextMode="Password"></asp:TextBox>
 </p>
 <p>
 <asp:CheckBox ID="RememberMe" runat="server" Text="Remember Me" />
 </p>
 <p>
 <asp:Button ID="LoginButton" runat="server" Text="Login" OnClick="LoginButton_Click" />
 </p>
 <p>
 <asp:Label ID="InvalidCredentialsMessage" runat="server" ForeColor="Red" Text="Your username or password is invalid. Please try again." 
 Visible="False"></asp:Label>
 </p>
</asp:Content>

The Login Page Contains Two TextBoxes, a CheckBox, a Button, and a Label

図 09: ログイン ページには、2 つの TextBox、1 つの CheckBox、1 つの Button、1 つの Label が含まれています (フルサイズ画像を表示するにはこちらをクリックしてください)

最後に、LoginButton の Click イベントのイベント ハンドラーを作成します。 デザイナーから Button コントロールをダブルクリックするだけで、このイベント ハンドラーが作成されます。

指定された資格情報が有効かどうかの判断

次に、ボタンの Click イベント ハンドラーにタスク 2 を実装する必要があります。これは、指定された資格情報が有効かどうかを判断します。 これを行うには、指定された資格情報が既知の資格情報と一致するかどうかを判断できるように、すべてのユーザーの資格情報を保持するユーザー ストアが必要です。

ASP.NET 2.0 より前は、開発者は独自のユーザー ストアを実装し、指定された資格情報をそのストアと照合して検証するコードを記述する責任がありました。 そのための開発者の一般的な方法は、ユーザー ストアをデータベースに実装し、UserName、Password、Email、LastLoginDate などの列を持つ Users という名前のテーブルを作成します。 このテーブルに、ユーザー アカウントごとに 1 つのレコードを含めます。 ユーザーが指定した資格情報を確認します。これは、一致するユーザー名をデータベースに照会し、データベース内のパスワードが指定されたパスワードに対応していることを確認することで行います。

ASP.NET 2.0 では、開発者はメンバーシップ プロバイダーのいずれかを使用してユーザー ストアを管理する必要があります。 このチュートリアル シリーズでは、SqlMembershipProvider を使用します。このプロバイダーでは、ユーザー ストアに SQL Server データベースが使用されます。 SqlMembershipProvider を使用する場合は、このプロバイダーが予期するテーブル、ビュー、ストアド プロシージャを含む特定のデータベース スキーマを実装する必要があります。 このスキーマの実装方法については、「SQL Server でメンバーシップ スキーマを作成する」チュートリアルを参照してください。 メンバーシップ プロバイダーを用意すると、ユーザーの資格情報の検証は、Membership クラスValidateUser(username, password) メソッドを呼び出すのと同じくらい簡単です。このメソッドは、usernamepassword の組み合わせの有効性を示すブール値を返します。 SqlMembershipProvider のユーザー ストアをまだ実装していないため、現時点では Membership クラスの ValidateUser メソッドを使用できません。

独自のカスタム Users データベース テーブル (SqlMembershipProvider の実装後使われなくなる) を作成する代わりに、ログイン ページ自体の中で、有効な資格情報をハードコーディングします。 LoginButton の Click イベント ハンドラーに、次のコードを追加します。

Protected Sub LoginButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles LoginButton.Click
 ' Three valid username/password pairs: Scott/password, Jisun/password, and Sam/password.
 Dim users() As String = {"Scott", "Jisun", "Sam"}
 Dim passwords() As String = {"password", "password", "password"}
 For i As Integer = 0 To users.Length - 1
 Dim validUsername As Boolean = (String.Compare(UserName.Text, users(i), True) = 0)
 Dim validPassword As Boolean = (String.Compare(Password.Text, passwords(i), False) = 0)
 If validUsername AndAlso validPassword Then
 ' TODO: Log in the user...
 ' TODO: Redirect them to the appropriate page
 End If
 Next
 ' If we reach here, the user's credentials were invalid
 InvalidCredentialsMessage.Visible = True
End Sub

ご覧のように、Scott、Jisun、Sam の 3 つの有効なユーザー アカウントがあり、これら 3 つのすべてが同じパスワード (パスワード) を持っています。 このコードは、有効なユーザー名とパスワードの一致を探すユーザーとパスワードの配列をループします。 ユーザー名とパスワードの両方が有効な場合は、ユーザーをログインさせ、適切なページにリダイレクトする必要があります。 資格情報が無効な場合は、InvalidCredentialsMessage ラベルを表示します。

前述のとおり、ユーザーが有効な資格情報を入力すると、適切なページにリダイレクトされます。 それでは、その適切なページとは何でしょうか。 ユーザーがページにアクセスしたときに、表示が許可されていないと、FormsAuthenticationModule によって自動的にログイン ページにリダイレクトされることを思い出してください。 その際、要求された URL が、ReturnUrl パラメーターを介してクエリ文字列に含まれます。 つまり、ユーザーが ProtectedPage.aspx にアクセスしようとしたときに、そのアクセスが許可されていない場合、FormsAuthenticationModule はユーザーを次の宛先にリダイレクトします。

Login.aspx?ReturnUrl=ProtectedPage.aspx

正常にログインすると、そのユーザーは ProtectedPage.aspx にリダイレクトされます。 または、ユーザーは自分の意思でログイン ページにアクセスすることもできます。 その場合、そのユーザーをログインさせた後に、ユーザーをルート フォルダーの Default.aspx ページにリダイレクトする必要があります。

ユーザーのログイン

指定された資格情報が有効であると仮定すると、フォーム認証チケットを作成して、ユーザーをサイトにログインさせる必要があります。 System.Web.Security 名前空間FormsAuthentication クラスには、フォーム認証システムを介してユーザーをログインおよびログアウトするための各種メソッドが用意されています。 FormsAuthentication クラスにはいくつかのメソッドがありますが、この段階で関係がある 3 つのメソッドは次のとおりです。

  • GetAuthCookie(username, persistCookie) - 指定された名前の username のフォーム認証チケットを作成します。 次に、このメソッドは、認証チケットの内容を保持する HttpCookie オブジェクトを作成して返します。 persistCookie が True の場合は、永続的な Cookie が作成されます。
  • SetAuthCookie(username, persistCookie) - GetAuthCookie(username, persistCookie) メソッドを呼び出し、フォーム認証 Cookie を生成します。 次に、このメソッドは、GetAuthCookie によって返された Cookie を Cookie コレクションに追加します (Cookie ベースのフォーム認証が使用されていると仮定します。それ以外の場合、このメソッドは Cookie なしのチケット ロジックを処理する内部クラスを呼び出します)。
  • RedirectFromLoginPage(username, persistCookie) - このメソッドは SetAuthCookie(username, persistCookie) を呼び出し、ユーザーを適切なページにリダイレクトします。

GetAuthCookie は、Cookie を Cookie コレクションに書き込む前に、認証チケットを変更する必要がある場合に便利です。 SetAuthCookie は、フォーム認証チケットを作成して Cookie コレクションに追加するものの、ユーザーを適切なページにリダイレクトしたくない場合に便利です。 場合によって、ユーザーをログイン ページに留めたいことと、別のページにリダイレクトしたいことがあります。

ここではユーザーをログインさせ、適切なページにリダイレクトすることにし、RedirectFromLoginPage を使用します。 LoginButton の Click イベント ハンドラーを更新し、コメントアウトされた 2 つの TODO 行を次のコード行に置き換えます。

FormsAuthentication.RedirectFromLoginPage(UserName.Text, RememberMe.Checked)

フォーム認証チケットを作成するときは、フォーム認証チケットの username パラメーターに UserName TextBox の Text プロパティを使用し、persistCookie パラメーターの RememberMe CheckBox のチェック状態を使用します。

ログイン ページをテストするには、ブラウザーでログイン ページにアクセスします。 まずは、ユーザー名 Nope や間違ったパスワードなど、無効な資格情報を入力します。 ログイン ボタンをクリックすると、ポストバックが発生し、InvalidCredentialsMessage ラベルが表示されます。

The InvalidCredentialsMessage Label is Displayed When Entering Invalid Credentials

図 10: 無効な資格情報を入力すると、InvalidCredentialsMessage ラベルが表示されます (フルサイズ画像を表示するにはこちらをクリックしてください)

次に、有効な資格情報を入力し、ログイン ボタンをクリックします。 今度はポストバックが発生すると、フォーム認証チケットが作成され、自動的に Default.aspx に戻されます。 この時点で Web サイトにログインしましたが、現在ログインしていることを示す視覚的な手掛かりはありません。 手順 4 では、ユーザーがログインしているかどうかをプログラムによって判定する方法と、ページにアクセスするユーザーを識別する方法について説明します。

手順 5 では、ユーザーを Web サイトからログアウトさせる手法について説明します。

ログイン ページのセキュリティ保護

ユーザーが自分の資格情報を入力してログイン ページ フォームを送信すると、パスワードを含む資格情報がインターネット経由で "プレーンテキスト" で Web サーバーに送信されます。 つまり、ネットワーク トラフィックをスニッフィングしているハッカーは、ユーザー名とパスワードを確認できるということです。 これを防ぐために、Secure Socket Layer (SSL) を使用してネットワーク トラフィックを暗号化することが不可欠です。 これにより、資格情報 (およびページ全体の HTML マークアップ) が、ブラウザーを離れた瞬間から Web サーバーによって受信されるまで暗号化されます。

Web サイトに機密情報が含まれていない場合は、SSL を使用する必要があるのは、ログイン ページと、その他のユーザーのパスワードがネットワーク上をプレーン テキストで送信されないようにするページのみです。 既定では、改ざんを防ぐ目的で暗号化とデジタル署名の両方が行われるので、フォーム認証チケットをセキュリティ保護しようと心配する必要はありません。 フォーム認証チケットのセキュリティの詳細については、次のチュートリアルで説明します。

Note

多くの金融および医療 Web サイトは、認証されたユーザーがアクセスできるすべてのページで SSL を使用するように構成されています。 このような Web サイトを構築する場合は、フォーム認証チケットがセキュリティで保護された接続経由でのみ送信されるように、フォーム認証システムを構成できます。

手順 4: 認証済みの訪問者の検出とその ID の特定

この時点で、フォーム認証を有効にし、基本的なログイン ページを作成しましたが、ユーザーが認証されているか匿名であるかを判断する方法についてはまだ説明していません。 シナリオによっては、ページにアクセスしているのが認証されたユーザーか匿名ユーザーかに応じて、異なるデータや情報を表示できます。 さらに、多くの場合、認証されたユーザーの ID を把握する必要があります。

既存の Default.aspx ページを拡張して、これらの手法を説明します。 Default.aspx に、AuthenticatedMessagePanel という名前のコントロールと AnonymousMessagePanel という名前のコントロールの 2 つの Panel コントロールを追加します。 最初のパネルに、WelcomeBackMessage という名前の Label コントロールを追加します。 2 番目のパネルに HyperLink コントロールを追加し、その Text プロパティを Log In に設定し、NavigateUrl プロパティを ~/Login.aspx に設定します。 この時点で、Default.aspx の宣言型マークアップは次のようになります。

<%@ Page Language="VB" MasterPageFile="~/Site.master" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" Title="Untitled Page" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" Runat="Server">
 <asp:Panel runat="server" ID="AuthenticatedMessagePanel">
 <asp:Label runat="server" ID="WelcomeBackMessage"></asp:Label>
 </asp:Panel>
 <asp:Panel runat="Server" ID="AnonymousMessagePanel">
 <asp:HyperLink runat="server" ID="lnkLogin" Text="Log In" NavigateUrl="~/Login.aspx"></asp:HyperLink>
 </asp:Panel>
</asp:Content>

既におわかりのように、ここでのアイデアは、認証された訪問者にのみ AuthenticatedMessagePanel を表示し、匿名の訪問者にのみ AnonymousMessagePanel を表示することです。 これを実現するには、ユーザーがログインしているかどうかに応じて、これらのパネルの表示プロパティを設定する必要があります。

Request.IsAuthenticated プロパティは、要求が認証されたかどうかを示すブール値を返します。 Page_Load イベント ハンドラー コードに次のコードを入力します。

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
 If Request.IsAuthenticated Then
 WelcomeBackMessage.Text = "Welcome back!"
 AuthenticatedMessagePanel.Visible = True
 AnonymousMessagePanel.Visible = False
 Else
 AuthenticatedMessagePanel.Visible = False
 AnonymousMessagePanel.Visible = True
 End If
End Sub

このコードを配置した状態で、ブラウザーから Default.aspx にアクセスします。 まだログインしていないと仮定すると、ログイン ページへのリンクが表示されます (図 11 を参照)。 このリンクをクリックし、サイトにログインします。 手順 3 で説明したように、資格情報を入力すると、Default.aspx に戻りますが、今度はページに "Welcome back!" メッセージが表示されます (図 12 を参照)。

When Visiting Anonymously, a Log In Link is Displayed

図 11: 匿名でアクセスすると、ログイン リンクが表示されます (フルサイズ画像を表示するにはこちらをクリックしてください)

Authenticated Users are Shown the Welcome back! Message

図 12: 認証されたユーザーに、"Welcome back!" メッセージが表示されます (フルサイズ画像を表示するにはこちらをクリックしてください)

HttpContext オブジェクトUser プロパティを使用して、現在ログオンしているユーザーの ID を確認できます。 HttpContext オブジェクトは、現在の要求に関する情報を表し、Response、Request、Session などの一般的な ASP.NET オブジェクトのためのホームです。 User プロパティは、現在の HTTP 要求のセキュリティ コンテキストを表し、IPrincipal インターフェイスを実装します。

User プロパティは、FormsAuthenticationModule によって設定されます。 具体的には、FormsAuthenticationModule が受信する要求の中でフォーム認証チケットを見つけると、新しい GenericPrincipal オブジェクトが作成され、User プロパティに割り当てられます。

プリンシパル オブジェクト (GenericPrincipal など) は、ユーザーの ID とユーザーが属するロールに関する情報を提供します。 IPrincipal インターフェイスは、次の 2 つのメンバーを定義します。

次のコードを使用して、現在の訪問者の名前を確認できます。

Dim currentUsersName As String = User.Identity.Name

フォーム認証を使用する場合、GenericPrincipal の Identity プロパティに対して FormsIdentity オブジェクトが作成されます。 FormsIdentity クラスは、常にフォームの AuthenticationType プロパティに対して文字列 Forms を返し、IsAuthenticated プロパティに対して True を返します。 Name プロパティは、フォーム認証チケットの作成時に指定されたユーザー名を返します。 これら 3 つのプロパティに加えて、FormsIdentity には、Ticket プロパティを介した基になる認証チケットへのアクセスが含まれます。 Ticket プロパティは、Expiration、IsPersistent、IssueDate、Name などのプロパティを持つ FormsAuthenticationTicket 型のオブジェクトを返します。

ここで重要なのは、FormsAuthentication.GetAuthCookie(username, persistCookie), FormsAuthentication.SetAuthCookie(username, persistCookie) メソッドと FormsAuthentication.RedirectFromLoginPage(username, persistCookie) メソッドで指定された username パラメーターが、User.Identity.Name によって返される値と同じであるという点です。 さらに、これらのメソッドによって作成された認証チケットを使用するには、User.Identity を FormsIdentity オブジェクトにキャストしてから、Ticket プロパティにアクセスします。

Dim ident As FormsIdentity = CType(User.Identity, FormsIdentity)

Dim authTicket As FormsAuthenticationTicket = ident.Ticket

次は、Default.aspx に、よりパーソナライズされたメッセージを提供します。 WelcomeBackMessage ラベルの Text プロパティに "Welcome back, username!" という文字列が割り当てられるように、Page_Load イベント ハンドラーを更新します。

WelcomeBackMessage.Text = "Welcome back, " & User.Identity.Name & "!"

図 13 は、ユーザー Scott としてログインするときのこの変更の効果を示しています。

The Welcome Message Includes the Currently Logged In User's Name

図 13: ウェルカム メッセージに、現在ログインしているユーザーの名前が含まれています (フルサイズ画像を表示するにはこちらをクリックしてください)

LoginView コントロールと LoginName コントロールの使用

認証されたユーザーと匿名ユーザーに異なるコンテンツを表示するのは、よくある要件です。また、現在ログオンしているユーザーの名前を表示するのも多くの場合に必要です。 そのため、ASP.NET には、図 13 に示すのと同じ機能を提供する 2 つの Web コントロールが含まれていますが、そのためのコード行は 1 行も記述する必要がありません。

LoginView コントロールは、認証されたユーザーと匿名ユーザーに異なるデータを簡単に表示できるようにするテンプレート ベースの Web コントロールです。 LoginView には、次の 2 つの定義済みテンプレートが含まれています。

  • AnonymousTemplate - このテンプレートに追加されたマークアップは、匿名の訪問者にのみ表示されます。
  • LoggedInTemplate - このテンプレートのマークアップは、認証されたユーザーにのみ表示されます。

次は、サイトのマスター ページ Site.master に、LoginView コントロールを追加します。 ただし、LoginView コントロールだけでなく、新しい ContentPlaceHolder コントロールとの両方を追加し、その新しい ContentPlaceHolder 内に LoginView コントロールを配置します。 こうする理由は、この後すぐにわかります。

Note

AnonymousTemplate と LoggedInTemplate に加えて、LoginView コントロールにはロール固有のテンプレートを含められます。 ロール固有のテンプレートは、指定されたロールに属するユーザーにのみ、マークアップを表示します。 今後のチュートリアルでは、LoginView コントロールのロールベースの機能について説明します。

まず、ナビゲーション <div> 要素内のマスター ページに LoginContent という名前の ContentPlaceHolder を追加します。 これには、ツールボックスからソース ビューに ContentPlaceHolder コントロールをドラッグし、結果のマークアップを " TODO: Menu will go here" テキストのすぐ上に配置するだけです。

<div id="navigation">
 <asp:ContentPlaceHolder ID="LoginContent" runat="server">
 </asp:ContentPlaceHolder>
 TODO: Menu will go here...
</div>

次に、LoginContent ContentPlaceHolder 内に LoginView コントロールを追加します。 マスター ページの ContentPlaceHolder コントロールに配置されたコンテンツは、ContentPlaceHolder の既定のコンテンツと見なされます。 つまり、このマスター ページを使用する ASP.NET ページは、ContentPlaceHolder ごとに独自のコンテンツを指定でき、マスター ページの既定のコンテンツを使用することもできます。

LoginView およびその他のログイン関連のコントロールは、ツールボックスの [ログイン] タブにあります。

The LoginView Control in the Toolbox

図 14: ツールボックスの LoginView コントロール (フルサイズ画像を表示するにはこちらをクリックしてください)

次に、LoginView コントロールの直後に、ContentPlaceHolder 内に 2 つの <br /> 要素を追加します。 この時点で、ナビゲーション <div> 要素のマークアップは次のようになります。

<div id="navigation">
 <asp:ContentPlaceHolder ID="LoginContent" runat="server">
 <asp:LoginView ID="LoginView1" runat="server">
 </asp:LoginView>
 <br /><br />
 </asp:ContentPlaceHolder>
 TODO: Menu will go here...
</div>

LoginView のテンプレートは、デザイナーまたは宣言型マークアップから定義できます。 Visual Studio のデザイナーから、LoginView のスマート タグを展開します。このタグには、構成済みのテンプレートがドロップダウン リストに一覧表示されます。 AnonymousTemplate に "Hello, stranger" というテキストを入力します。次に、HyperLink コントロールを追加し、Text プロパティと NavigateUrl プロパティをそれぞれ Log In と ~/Login.aspx に設定します。

AnonymousTemplate を構成した後、LoggedInTemplate に切り替えて、"Welcome back, " というテキストを入力します。 次に、LoginName コントロールをツールボックスから LoggedInTemplate にドラッグし、"Welcome back, " というテキストの直後に配置します。 LoginName コントロールは、その名前が示すように、現在ログインしているユーザーの名前を表示します。 内部的には、LoginName コントロールは単に User.Identity.Name プロパティを出力します

LoginView のテンプレートにこれらの追加を行った後は、マークアップは次のようになります。

<div id="navigation">
 <asp:ContentPlaceHolder ID="LoginContent" runat="server">
 <asp:LoginView ID="LoginView1" runat="server">
 <LoggedInTemplate>
 Welcome back, <asp:LoginName ID="LoginName1" runat="server" />.
 </LoggedInTemplate>
 <AnonymousTemplate>
 Hello, stranger. <asp:HyperLink ID="lnkLogin" runat="server" NavigateUrl="~/Login.aspx">Log In</asp:HyperLink>
 </AnonymousTemplate>
 </asp:LoginView>
 <br /><br />
 </asp:ContentPlaceHolder>
 TODO: Menu will go here...
</div>

Site.master マスター ページにこの追加を行った状態では、Web サイト内の各ページに、ユーザーが認証されているかどうかに応じて異なるメッセージが表示されます。 図 15 は、ユーザー Jisun がブラウザーを介してアクセスしたときの Default.aspx ページを示しています。 "Welcome back, Jisun" というメッセージが、左側のマスター ページのナビゲーション セクション (先ほど追加した LoginView コントロールを使用) と、Default.aspx のコンテンツ領域 (パネル コントロールとプログラム ロジックを使用) にそれぞれ 1 回、合計 2 回繰り返されます。

The LoginView Control Displays Welcome back, Jisun.

図 15: LoginView コントロールに "Welcome back, Jisun" が表示されます。 (クリックするとフルサイズの画像が表示されます)

マスター ページに LoginView を追加したため、これはサイトのすべてのページに表示されます。 ただし、このメッセージを表示したくない Web ページもある場合があります。 このようなページの 1 つがログイン ページです。ログイン ページに、ログイン ページへのリンクはあるべきでないからです。 マスター ページの ContentPlaceHolder に LoginView コントロールを配置したので、この既定のマークアップをコンテンツ ページでオーバーライドできます。 Login.aspx を開き、デザイナーに移動します。 マスター ページの LoginContent ContentPlaceHolder 用の Login.aspx 内で Content コントロールを明示的に定義していないため、ログイン ページには、この ContentPlaceHolder 用にマスター ページの既定のマークアップが表示されます。 これは、デザイナーで確認できます。LoginContent ContentPlaceHolder に、既定のマークアップ (LoginView コントロール) が表示されることがわかります。

The Login Page Shows the Default Content for the Master Page's LoginContent ContentPlaceHolder

図 16: ログイン ページは、マスター ページの LoginContent ContentPlaceHolder の既定のコンテンツを示しています (フルサイズ画像を表示するにはこちらをクリックしてください)

LoginContent ContentPlaceHolder の既定のマークアップをオーバーライドするには、デザイナーで領域を右クリックし、コンテキスト メニューから [カスタム コンテンツの作成] オプションを選択するだけです。 (Visual Studio 2008 を使用する場合、ContentPlaceHolder には、選択したときに、同じオプションを提供するスマート タグが含まれます)。これにより、ページのマークアップに新しい Content コントロールが追加されるため、このページのカスタム コンテンツを定義できます。 "Please log in" などのカスタム メッセージをここに追加することもできますが、このメッセージは空白のままにしておきます。

Note

Visual Studio 2005 では、カスタム コンテンツを作成すると、ASP.NET ページに空の Content コントロールが作成されます。 ただし、Visual Studio 2008 では、カスタム コンテンツを作成すると、マスター ページの既定のコンテンツが、新しく作成された Content コントロールにコピーされます。 Visual Studio 2008 を使用している場合は、新しい Content コントロールを作成した後で、マスター ページからコピーされたコンテンツを消去します。

図 17 は、この変更を行った後にブラウザーからアクセスしたときの Login.aspx ページを示しています。 Default.aspx にアクセスするときと同じように、左側のナビゲーション <div> に "Hello, stranger" または "Welcome back, ユーザー名" メッセージがないことに注目してください。

The Login Page Hides the Default LoginContent ContentPlaceHolder's Markup

図 17: ログイン ページは既定の LoginContent ContentPlaceHolder のマークアップを非表示にします (フルサイズ画像を表示するにはこちらをクリックしてください)

手順 5: ログアウト

手順 3 では、ユーザーをサイトにログインさせるためのログイン ページを作成する方法を説明しましたが、ユーザーをログアウトさせる方法はまだ説明していません。FormsAuthentication クラスには、ユーザーをログインさせるメソッドに加えて、SignOut メソッドも用意されています。 SignOut メソッドは、単にフォーム認証チケットを破棄します。そうすることで、ユーザーをサイトからログアウトさせます。

ログアウト リンクを提供するのは、実装されることが多い機能です。このために、ASP.NET にユーザーをログアウトさせる用途専用に設計されたコントロールが用意されています。LoginStatus コントロールには、ユーザーの認証状態に応じて、ログイン LinkButton またはログアウト LinkButton が表示されます。 Login LinkButton は匿名ユーザーを対象にレンダリングされ、Logout LinkButton は認証されたユーザーを対象に表示されます。 Login および Logout の各 LinkButton のテキストは、LoginStatus の LoginText プロパティと LogoutText プロパティを使用して構成できます。

Login LinkButton をクリックするとポストバックが発生し、そこからログイン ページへのリダイレクトが発行されます。 Logout LinkButton をクリックすると、LoginStatus コントロールが FormsAuthentication.SignOff メソッドを呼び出し、ユーザーをページにリダイレクトします。 ログオフしたユーザーがリダイレクトされるページは、LogoutAction プロパティに依存します。このプロパティは、次の 3 つの値のいずれかに割り当てることができます。

  • Refresh - 既定値。直前にアクセスを試みたページにユーザーをリダイレクトします。 ユーザーがアクセスを試みたページが、匿名ユーザーを許可していない場合、そのユーザーは、FormsAuthenticationModule によってログイン ページに自動的にリダイレクトされます。

読者はここでリダイレクトするのはなぜかと疑問に思われるかもしれません。 ユーザーは同じページに残りたいかもしれないのに、明示的なリダイレクトが必要なのはなぜでしょうか。 この理由は、Logoff LinkButton をクリックした時点では、ユーザーはまだ Cookie コレクションにフォーム認証チケットを保持しているためです。 その結果、ポストバック要求は認証済みの要求になります。 LoginStatus コントロールは SignOut メソッドを呼び出しますが、これは、FormsAuthenticationModule がユーザーを認証した後に発生します。 したがって、明示的にリダイレクトすることによって、ブラウザーにページを再要求させます。 ブラウザーがページを要求し直すまでの間に、フォーム認証チケットは削除されているため、受信する要求は匿名になります。

  • Redirect - ユーザーは、LoginStatus の LogoutPageUrl プロパティで指定された URL にリダイレクトされます。
  • RedirectToLoginPage - ユーザーは、ログイン ページにリダイレクトされます。

次は、マスター ページに LoginStatus コントロールを追加し、Redirect オプションを使用して、サインアウトされたことを確認するメッセージを表示するページにユーザーをリダイレクトするように構成します。まず、Logout.aspx という名前のルート ディレクトリにページを作成します。 このページを Site.master マスター ページに関連付けるのを忘れないでください。 次に、ページのマークアップに、ユーザーがログアウトされたことを説明するメッセージを入力します。

次に、Site.master マスター ページに戻り、LoginContent ContentPlaceHolder の LoginView の下に LoginStatus コントロールを追加します。 LoginStatus コントロールの LogoutAction プロパティを Redirect に設定し、その LogoutPageUrl プロパティを ~/Logout.aspx に設定します。

<div id="navigation">
 <asp:ContentPlaceHolder ID="LoginContent" runat="server">
 <asp:LoginView ID="LoginView1" runat="server">
 <LoggedInTemplate>
 Welcome back, <asp:LoginName ID="LoginName1" runat="server" />.
 </LoggedInTemplate>
 <AnonymousTemplate>
 Hello, stranger. <asp:HyperLink ID="lnkLogin" runat="server" NavigateUrl="~/Login.aspx">Log In</asp:HyperLink>
 </AnonymousTemplate>
 </asp:LoginView>
 <br />
 <asp:LoginStatus ID="LoginStatus1" runat="server" LogoutAction="Redirect" LogoutPageUrl="~/Logout.aspx" />
 <br /><br />
 </asp:ContentPlaceHolder>
 TODO: Menu will go here...
</div>

LoginStatus は LoginView コントロールの外部にあるため、匿名ユーザーと認証済みユーザーの両方に対して表示されますが、これに問題はありません。LoginStatus には、Login または Logout LinkButton が正しく表示されるためです。 LoginStatus コントロールを追加すると、AnonymousTemplate 内の Log In HyperLink は余分になるため、削除します。

図 18 は、Jisun がアクセスしたときの Default.aspx を示しています。 左側の列には、ログアウトするためのリンクと共に、"Welcome back, Jisun along" というメッセージが表示されることに注意してください。ログアウト LinkButton をクリックするとポストバックが発生し、Jisun がシステムからサインアウトされ、Logout.aspx にリダイレクトされます。 図 19 に示すように、Jisun は Logout.aspx に達するまでの間に既にサインアウトされているため、この時点では匿名になっています。 その結果、左側の列に、Welcome, stranger というテキストと、ログイン ページへのリンクが表示されます。

Default.aspx Shows Welcome Back, Jisun Along with a Logout LinkButton

図 18: Default.aspx に "Welcome Back, Jisun Along" とログアウト LinkButton が示されます (フルサイズ画像を表示するにはこちらをクリックしてください)

Logout.aspx Shows Welcome, stranger Along with a Login LinkButton

図 19: Logout.aspx は "Welcome, stranger" とログイン LinkButton を示しています (フルサイズ画像を表示するにはこちらをクリックしてください)

Note

Logout.aspx ページは、マスター ページの LoginContent ContentPlaceHolder を非表示にするようにカスタマイズすることをお勧めします (Login.aspx のために手順 4 で実施した方法と同様)。 その理由は、LoginStatus コントロール ("Hello, stranger" の下) によってレンダリングされる Login LinkButton が、ログイン ページにユーザーをリダイレクトし、このときに ReturnUrl クエリ文字列パラメーターの現在の URL を渡すためです。 つまり、ログアウトしたユーザーがこの LoginStatus の Login LinkButton をクリックし、その後ログインすると、そのユーザーは Logout.aspx に再度リダイレクトされることになり、ユーザーは混乱するはずです。

まとめ

このチュートリアルでは、フォーム認証ワークフローを調べることから始め、ASP.NET アプリケーションでフォーム認証を実装する方法を実践しました。 フォーム認証は、FormsAuthenticationModule を利用することによって行われます。これには、フォーム認証チケットに基づくユーザーの識別と、承認されていないユーザーのログイン ページへのリダイレクトという 2 つの役割があります。

.NET Framework の FormsAuthentication クラスには、フォーム認証チケットを作成、検査、削除するためのメソッドが含まれています。 Request.IsAuthenticated プロパティと User オブジェクトは、要求が認証されているかどうかを判断するためのプログラムによる追加のサポートと、ユーザーの ID に関する情報を提供します。 LoginView、LoginStatus、LoginName の各 Web コントロールもあります。開発者はこれらを使用して、多くの一般的なログイン関連タスクをコードなしで簡単に実行できます。 これらの Web コントロールとその他のログイン関連の Web コントロールについては、今後のチュートリアルで詳しく説明します。

このチュートリアルでは、フォーム認証の概要について説明しました。 さまざまな構成オプション、Cookie なしのフォーム認証チケットの機能方法、ASP.NET がフォーム認証チケットの内容を保護する方法については、取り上げていません。 これらのトピックについては、次のチュートリアルで詳しく説明します。

プログラミングに満足!

もっと読む

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

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

作成者について

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

特別な感謝

このチュートリアル シリーズは、多くの役に立つ校閲者によってレビューされました。 このチュートリアルのリード レビュー担当者には、Alicja Maziarz、John Suru、Toria Murphy が含まれます。 今後の MSDN の記事を確認することに関心がありますか? その場合は、mitchell@4guysfromrolla.com までご一報ください。