次の方法で共有


フォーム認証の概要 (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 との相互運用性の向上

コードのダウンロードまたは 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 Unauthorized 状態を返します。 Windows 認証のシナリオでは、HTTP 401 状態がブラウザーに返されます。 この状態コードにより、ブラウザーはモーダル ダイアログ ボックスを使用してユーザーに資格情報の入力を求めます。 ただし、フォーム認証では、FormsAuthenticationModule がこの状態を検出し、代わりに HTTP 302 Redirect 状態を介してログイン ページにリダイレクトするように変更するため、「HTTP 401 Unauthorized」状態はブラウザーに送信されません。

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

The Forms Authentication Workflow

図 1: フォーム認証ワークフロー

認証チケットを記憶してページにアクセスする

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

Cookie の 1 つの側面は、その有効期限です。これは、ブラウザーが Cookie を破棄する日時です。 フォーム認証 Cookie の有効期限が切れると、ユーザーは認証されなくなり、匿名になります。 公共のターミナルからアクセスするユーザーが望むのは、ブラウザー終了時に認証チケットの有効期限が切れるようにすることです。 一方、自宅では認証チケットを記憶させてブラウザーの再起動に使用し、サイトにアクセスするたびに再ログインする必要がないようにしたいと考えます。 多くの場合、この決定は、ユーザーがログイン ページの [記憶する] チェックボックスを選択することで実行されます。 手順 3 では、ログイン ページで [記憶する] チェックボックスを実装する方法を説明します。 次のチュートリアルでは、認証チケットのタイムアウト設定について詳しく説明します。

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 の別のエディションを使用している場合も手順はほぼ同じです。明確な違いがある場合は、その旨が説明されます。

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 固有のマークアップを削除しないと機能しません。

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

図 2: 新しいファイル システムベースの Web サイトを作成する (フルサイズ画像を表示するにはこちらをクリックしてください)

マスター ページを追加する

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

Add a Master Page Named Site.master to the Website

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

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

<%@ Master Language="C#" AutoEventWireup="true" CodeFile="Site.master.cs" 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> 内で表示できます。 マスター ページには 1 つの ContentPlaceHolder (MainContent) がありますが、複数の ContentPlaceHolder がマスター ページに含まれる場合もあります。

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

The Master Page, When Viewed Through the Design View

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

コンテンツ ページを作成する

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

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

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

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

Use the Site.master Master Page

図 6: Site.master マスター ページを使用する

Note

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

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

<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="Default.aspx.cs" 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> 要素を使用して指定されます。<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

図 7: プロジェクトに 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 ファイルであるため、大文字と小文字を区別することが重要です。 必ず mode 属性を Forms に設定し、大文字の "F" を使用します。 小文字の "forms" などを使用すると、ブラウザーからサイトにアクセスするときに構成エラーが発生します。

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

手順 3: ログイン ページを構築する

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

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

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

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

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

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

Add a New ASP.NET Page Named Login.aspx

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

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

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

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

<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="Login.aspx.cs" 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

図 9: 2 つのテキスト ボックス、1 つのチェックボックス、1 つのボタン、1 つのラベルで構成されるログイン ページ (フルサイズ画像を表示するにはこちらをクリックしてください)

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

指定された資格情報が有効かどうかを判定する

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

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

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

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

protected void LoginButton_Click(object sender, EventArgs e)
{
    // Three valid username/password pairs: Scott/password, Jisun/password, and Sam/password.
    string[] users = { "Scott", "Jisun", "Sam" };
    string[] passwords = { "password", "password", "password" };
    for (int i = 0; i < users.Length; i++)
    {
        bool validUsername = (string.Compare(UserName.Text, users[i], true) == 0);
        bool validPassword = (string.Compare(Password.Text, passwords[i], false) == 0);
        if (validUsername && validPassword)
        {
            // TODO: Log in the user...
            // TODO: Redirect them to the appropriate page
        }
    }
    // If we reach here, the user's credentials were invalid
    InvalidCredentialsMessage.Visible = true;
}

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

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

Login.aspx?ReturnUrl=ProtectedPage.aspx

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

ユーザーをログインさせる

指定された資格情報が有効であると仮定すると、フォーム認証チケットを作成して、ユーザーをサイトにログインさせる必要があります。 System.Web.Security namespace 名前空間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" やパスワード "wrong" など、無効な資格情報を入力します。 ログイン ボタンをクリックするとポストバックが発生し、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="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="Default.aspx.cs" 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 void Page_Load(object sender, EventArgs e)
{
    if (Request.IsAuthenticated)
    {
        WelcomeBackMessage.Text = "Welcome back!";
    
        AuthenticatedMessagePanel.Visible = true;
        AnonymousMessagePanel.Visible = false;
    }
    else
    {
        AuthenticatedMessagePanel.Visible = false;
        AnonymousMessagePanel.Visible = true;
    }
}

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

When Visiting Anonymously, a Log In Link is Displayed

図 11: 匿名でアクセスすると、[ログイン] リンクが表示される

Authenticated Users are Shown the

図 12: 認証済みユーザーに、"Welcome back!" が表示されるメッセージ

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

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

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

  • IsInRole(roleName) - 指定したロールにプリンシパルが属しているかどうかを示すブール値を返すメソッド。
  • Identity - IIdentity インターフェイスを実装するオブジェクトを返すプロパティ。 IIdentity インターフェイスは、AuthenticationTypeIsAuthenticatedName の 3 つのプロパティを定義します。

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

string currentUsersName = 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 プロパティにアクセスします。

FormsIdentity ident = User.Identity as FormsIdentity;
FormsAuthenticationTicket authTicket = 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 のコンテンツ領域 (Panel コントロールとプログラム ロジックを使用) にそれぞれ 1 回、合計 2 回繰り返されます。

The LoginView Control Displays

図 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, username" メッセージがないことに注目してください。

The Login Page Hides the Default LoginContent ContentPlaceHolder's Markup

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

手順 5: ログアウトする

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

ログアウト リンクを提供するのは、実装されることが多い機能です。このために、ASP.NET にユーザーをログアウトさせる用途専用に設計されたコントロールが用意されています。LoginStatus コントロールは、ユーザーの認証状態に応じて、"Login" LinkButton または "Logout" 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

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

Logout.aspx Shows

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

Note

Logout.aspx ページは、マスター ページの LoginContent ContentPlaceHolder を非表示にするようにカスタマイズすることをお勧めします (手順 4 で Login.aspx について実施した内容と同様)。 その理由は、LoginStatus コントロールによってレンダリングされる "Login" LinkButton ("Hello, stranger" の下) が、ログイン ページにユーザーをリダイレクトし、このときに 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 がどのようにフォーム認証チケットの内容を保護するかについては、取り上げていません。

プログラミングに満足!

もっと読む

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

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

著者について

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

特別な感謝

このチュートリアル シリーズは、多くの役に立つ校閲者によってレビューされました。 このチュートリアル シリーズは多数の協力的なレビュー担当者によるレビューを受けています。 このチュートリアルのリード レビュー担当者には、Alicja Maziarz、John Suru、Teresa Murphy が含まれます。 今後の MSDN の記事を確認することに関心がありますか? その場合は、 にmitchell@4GuysFromRolla.com行をドロップしてください。