次の方法で共有


セキュリティ保護された ASP.NET アプリケーションの構築 : 認証、認定、および通信のセキュリティ保護 フォーム認証を使用して GenericPrincipal オブジェクトを作成する方法

patterns and practices home

J.D. Meier, Alex Mackman, Michael Dunner, and Srinath Vasireddy
Microsoft Corporation

November 2002
日本語版最終更新日 2003 年 3 月 17 日

適用対象:
    Microsoft® ASP.NET
    Microsoft Visual Studio® .NET
    Microsoft SQL Server™ 2000

全体の概要については、「セキュリティ保護された ASP.NET アプリケーションの構築」の開始ページを参照してください。

要約 : ここでは、フォーム認証を使用する際の GenericPrincipal オブジェクトおよび FormsIdentity オブジェクトの作成および処理方法について説明します。

目次

必要条件
要約
関連資料

フォーム認証を使用するアプリケーションでは、Windows ドメインから独立して非 Windows 固有の認定スキームを作成するために、GenericPrincipal クラスと FormsIdentity クラスを共に使用したい場合が頻繁にあります。

たとえば、アプリケーションが次のような作業を行う場合です。

  • フォーム認証を使用してユーザー資格情報 (ユーザー名とパスワード) を取得します。
  • 入力された資格情報を、データベースや Microsoft® Active Directory® ディレクトリ サービスなどのデータ ストアと照合して、その妥当性を評価します。
  • データ ストアから取り出した値を基に、GenericPrincipal オブジェクトおよび FormsIdentity オブジェクトを作成します。これには、ユーザーのロール メンバシップの詳細が含まれている場合もあります。
  • これらのオブジェクトを使用して認定するかどうかの判断を下します。

ここでは、ユーザーを認証して独自のフォーム認証チケットを作成する、フォームを基にした Web アプリケーションの作成方法について説明します。このフォーム認証チケットには、ユーザーおよびロールに関する情報が格納されます。また、この情報を GenericPrincipal オブジェクトと FormsIdentity オブジェクトにマップし、その新しいオブジェクトを HTTP Web 要求のコンテキストに関連付けて、アプリケーション内の認定ロジックに使用する方法についても解説しています。

なお、ここでは GenericPrincipal オブジェクトと FormsIdentity オブジェクトの生成、およびフォーム認証チケットの処理を中心に取り上げています。Active Directory および SQL Server 2000 に対するユーザー認証の方法については、このガイドの次のトピックを参照してください。

必要条件

ハードウェア、ソフトウェア、ネットワーク インフラストラクチャ、スキル、知識、サービス パックの要件は、以下のとおりです。

  • Microsoft SQL Server® 2000
  • Microsoft Visual Studio® .NET 開発システム

また、Microsoft Visual C#® 開発ツールを使用した ASP.NET Web 開発に関する知識も必要です。

要約

ここでは、次の手順について説明します。

  1. ログオン ページを含む Web アプリケーションを作成する。
  2. フォーム認証を使用するよう Web アプリケーションを構成する。
  3. 認証されたユーザーの認証チケットを生成する。
  4. GenericPrincipal オブジェクトおよび FormsIdentity オブジェクトを構築する。
  5. アプリケーションをテストする。

1. ログオン ページを含む Web アプリケーションを作成する

ここでは新しい ASP.NET Web アプリケーションを作成します。このアプリケーションには、認証されたユーザーのみがアクセスできる既定のページ、およびユーザー資格情報を収集するために使用するログオン ページの 2 つのページが含まれます。

■ ログオン ページを含む Web アプリケーションを作成するには

  1. Visual Studio .NET を起動して、"GeneralPrincipalApp" という名前の新しい C# ASP.NET Web アプリケーションを作成します。

  2. WebForm1.aspx の名前を Logon.aspx に変更します。

  3. 次のコントロールを Logon.aspx に追加して、ログオン フォームを作成します。

    表 1 Logon.aspx コントロール

    コントロールの種類 テキスト ID
    Label ユーザー名 : -
    Label パスワード -
    TextBox - txtUserName
    TextBox - txtPassword
    Button ログオン btnLogon
  4. パスワード用の TextBox コントロールの TextMode プロパティを Password に設定します。

  5. ソリューション エクスプローラで、GenericPrincipalApp を右クリックし、[追加] をクリックして、[Web フォームの追加] をクリックします。

  6. 新しいフォームの名前として「default.aspx」と入力し、[開く] をクリックします。

2. フォーム認証を使用するよう Web アプリケーションを構成する

■ アプリケーションの Web.config ファイルを編集し、フォーム認証を使用するようアプリケーションを構成するには

  1. ソリューション エクスプローラから Web.config を開きます。
  2. <authentication> 要素を探し、mode 属性を Forms に変更します。
  3. <authentication> 要素の子要素として <forms> 要素を追加し、loginUrl、name、timeout、path の各属性を次のように設定します。
<authentication mode="Forms">
  <forms loginUrl="logon.aspx" name="AuthCookie" timeout="60" path="/">
  </forms>
</authentication>

  1. <authentication> 要素の下に次の <authorization> 要素を追加します。この要素を追加することにより、認証されたユーザー以外はアプリケーションにアクセスできなくなります。認証されていない要求は、前の手順で確立された <authentication> 要素の loginUrl 属性によって、Logon.aspx ページにリダイレクトされます。
<authorization> 
  <deny users="?" />
  <allow users="*" />
</authorization>

3. 認証されたユーザーの認証チケットを生成する

ここでは、認証されたユーザーの認証チケットを生成するコードを記述します。認証チケットとは、ASP.NET の FormsAuthenticationModule が使用する Cookie の一種です。

認証コードは、通常、入力されたユーザー名とパスワードをカスタム データベースまたは Active Directory で照合する必要があります。

この照合の詳細については、このガイドの次の説明を参照してください。

■ 認証されたユーザーの認証チケットを生成するには

  1. Logon.aspx.cs ファイルを開き、ファイルの先頭の既存の using ステートメントの下に次の using ステートメントを追加します。
using System.Web.Security;
  1. プライベート ヘルパ メソッド IsAuthenticated を WebForm1 クラスに追加します。このメソッドは、ユーザー名とパスワードを検証してユーザーを認証するために使用します。このコードでは、ユーザー名とパスワードのすべての組み合わせが有効であることを想定しています。
private bool IsAuthenticated( string username, string password )
{
  // Lookup code omitted for clarity
  // This code would typically validate the user name and password
  // combination against a SQL database or Active Directory
  // Simulate an authenticated user
  return true;
}

  1. 次の プライベート ヘルパ メソッド GetRoles を追加します。このメソッドは、ユーザーが属するロールの一覧を取得するために使用します。

    private string GetRoles( string username, string password )
    {
      // Lookup code omitted for clarity
      // This code would typically look up the role list from a database table.
      // If the user was being authenticated against Active Directory, the
      // Security groups and/or distribution lists that the user belongs to may be 
      // used instead
    
    
      // This GetRoles method returns a pipe delimited string containing roles
      // rather than returning an array, because the string format is convenient 
      // for storing in the authentication ticket / cookie, as user data
      return "Senior Manager|Manager|Employee";
    }
    
  2. デザイナ モードで Logon.aspx フォームを表示し、次に [ログオン] ボタンをダブルクリックして、クリック イベント ハンドラを作成します。

  3. ログオン フォームで入力されたユーザー名とパスワードを受け取る IsAuthenticated メソッドへの呼び出しを追加します。このメソッドの戻り値をブール型の変数に代入します。この戻り値は、ユーザーが認証されたかどうかを示します。

bool isAuthenticated = IsAuthenticated( txtUserName.Text, 
                                        txtPassword.Text );

  1. ユーザーが認証された場合は、GetRoles メソッドを呼び出し、ユーザーのロールの一覧を取得します。
if (isAuthenticated == true )
{
  string roles = GetRoles( txtUserName.Text, txtPassword.Text );

  1. 新しいフォーム認証チケットを作成します。認証チケットには、ユーザー名、有効期限、ユーザーが属するロールの一覧が含まれます。なお、認証チケットのユーザー データ プロパティは、ユーザーのロールの一覧を格納するために使用します。また、以下のコードでは、非永続的なチケットを作成します。チケット (Cookie) が永続的かどうかは、アプリケーションの構造によります。
  // Create the authentication ticket
  FormsAuthenticationTicket authTicket = new 
       FormsAuthenticationTicket(1,                          // version
                                 txtUserName.Text,           // user name
                                 DateTime.Now,               // creation
                                 DateTime.Now.AddMinutes(60),// Expiration
                                 false,                      // Persistent
                                 roles );                    // User data

  1. 次のコードを追加して、このチケットを表す暗号化された文字列を作成し、その文字列をデータとして HttpCookie オブジェクトに格納します。
  // Now encrypt the ticket.
  string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
  // Create a cookie and add the encrypted ticket to the 
  // cookie as data.
  HttpCookie authCookie = 
               new HttpCookie(FormsAuthentication.FormsCookieName,
                              encryptedTicket);

  1. 新しく作成した Cookie を、ユーザーのブラウザに返す Cookie コレクションに追加します。
  // Add the cookie to the outgoing cookies collection. 
  Response.Cookies.Add(authCookie); 

  1. 要求された元のページにユーザーをリダイレクトします。
// Redirect the user to the originally requested page
  Response.Redirect( FormsAuthentication.GetRedirectUrl(
                                                txtUserName.Text, 
                                                false ));
}

4. GenericPrincipal オブジェクトおよび FormsIdentity オブジェクトを生成する

アプリケーション認証イベント ハンドラを実装し、認証チケット内に格納されている情報を基に GenericPrincipal オブジェクトおよび FormsIdentity オブジェクトを生成する手順を次に示します。

■ GenericPrincipal オブジェクトおよび FormsIdentity オブジェクトを生成するには

  1. ソリューション エクスプローラから global.asax を開きます。
  2. コード ビューに切り替えて、次の using ステートメントをファイルの先頭に追加します。
using System.Web.Security;
using System.Security.Principal;

  1. Application_AuthenticateRequest イベント ハンドラを探して次のコードを追加し、要求で渡された Cookie コレクションから、フォーム認証の Cookie を取得します。

    // Extract the forms authentication cookie
    string cookieName = FormsAuthentication.FormsCookieName;
    HttpCookie authCookie = Context.Request.Cookies[cookieName];
    
    if(null == authCookie)
    {
      // There is no authentication cookie.
      return;
    } 
    
  2. 次のコードを追加して、フォーム認証の Cookie から認証チケットを取り出し、解読します。

    FormsAuthenticationTicket authTicket = null;
    try
    {
      authTicket = FormsAuthentication.Decrypt(authCookie.Value);
    }
    catch(Exception ex)
    {
      // Log exception details (omitted for simplicity)
      return;
    }
    
    if (null == authTicket)
    {
      // Cookie failed to decrypt.
      return; 
    } 
    
  3. 次のコードを追加して、ユーザーが最初に認証されたときにチケットに格納されたロール名のパイプ区切りの一覧を解析します。

// When the ticket was created, the UserData property was assigned a
// pipe delimited string of role names.
string[] roles = authTicket.UserData.Split(new char[]{'|'});

  1. 次のコードを追加して、チケット名から取得したユーザー名で FormsIdentity オブジェクトを作成し、この ID とユーザーのロール一覧を格納する GenericPrincipal オブジェクトを作成します。

    // Create an Identity object
    FormsIdentity id = new FormsIdentity( authTicket ); 
    
    // This principal will flow throughout the request.
    GenericPrincipal principal = new GenericPrincipal(id, roles);
    // Attach the new principal object to the current HttpContext object
    Context.User = principal;
    

5. アプリケーションをテストする

ここでは、default.aspx ページにコードを追加して現在の HttpContext オブジェクトに添付された GenericPrincipal オブジェクトの情報を表示し、この GenericPrincipal オブジェクトが正常に生成され現在の Web 要求に割り当てられたかどうかを確認します。次に、アプリケーションをビルドしてテストします。

■ アプリケーションをテストするには

  1. ソリューション エクスプローラで、default.aspx をダブルクリックします。
  2. default.aspx の Web フォームをダブルクリックして、ページ読み込みのイベント ハンドラを表示します。
  3. スクロールしてファイルの先頭を表示し、既存の using ステートメントの下に次の using ステートメントを追加します。
using System.Security.Principal;
  1. ページ読み込みのイベント ハンドラに戻り、次のコードを追加して、現在の Web 要求に関連付けられている GeneralPrincipal に添付された ID 名を表示します。
IPrincipal p = HttpContext.Current.User;
Response.Write( "Authenticated Identity is: " +  
                p.Identity.Name );
Response.Write( "<p>" );

  1. 次のコードを追加して、現在認証されている ID のロール メンバシップを調べます。

    if ( p.IsInRole("Senior Manager") )
      Response.Write( "User is in Senior Manager role<p>" );
    else
      Response.Write( "User is not in Senior Manager role<p>" );
    
    if ( p.IsInRole("Manager") )
      Response.Write( "User is in Manager role<p>" );
    else
      Response.Write( "User is not in Manager role<p>" );
    
    if ( p.IsInRole("Employee") )
      Response.Write( "User is in Employee role<p>" );
    else
      Response.Write( "User is not in Employee role<p>" );
    
    if ( p.IsInRole("Sales") )
      Response.Write( "User is in Sales role<p>" );
    else
      Response.Write( "User is not in Sales role<p>" );
    
  2. ソリューション エクスプローラで、default.aspx を右クリックして、[スタート ページに設定] をクリックします。

  3. [ビルド] メニューの [ソリューションのビルド] をクリックします。ビルド エラーが発生した場合は、これを解決します。

  4. Ctrl + F5 を押して、アプリケーションを実行します。default.aspx はスタート ページとして構成されているため、このページが最初に要求されます。

  5. 最初は認証チケットを持っていないため、ログオン ページにリダイレクトされます。任意のユーザー名とパスワードを入力し、[ログオン] をクリックします。

  6. default.aspx にリダイレクトされたこと、およびユーザー ID と正しいロールの詳細が表示されたことを確かめます。このユーザーは Senior Manager ロール、Manager ロール、Employee ロールのメンバであるはずです。ただしSales ロールのメンバではありません。

関連資料

詳細については、このガイドの次のトピックを参照してください。

patterns and practices home