C#.NET を使用してフォーム ベース認証を ASP.NET アプリケーションに実装する

この記事では、データベースを使用してユーザーを保存してフォーム ベース認証を実装する方法を示します。 クラス ライブラリの名前空間は、次.NET Framework参照します。

  • System.Data.SqlClient
  • System.Web.Security

元の製品バージョン:  ASP.NET
元の KB 番号:   301240

要件

次の一覧では、必要な推奨ハードウェア、ソフトウェア、ネットワーク インフラストラクチャ、およびサービス パックの概要を示します。

  • Visual Studio .NET
  • インターネット インフォメーション サービス (IIS) バージョン 5.0 以降
  • SQL Server

.NET を ASP.NET してアプリケーションをC#する

  1. .NET Visual Studio開きます。
  2. Web アプリケーションに新 ASP.NET 作成し、名前と場所を指定します。

[ファイル] ファイルでセキュリティ設定をWeb.configする

このセクションでは、フォーム ベース認証を使用するアプリケーションを構成するために、ASP.NET および構成セクションを追加および <authentication> <authorization> 変更する方法を示します。

  1. ソリューション エクスプローラーで、Web.config ファイルを開きます。

  2. 認証モードを Forms に 変更します

  3. タグを <Forms> 挿入し、適切な属性を入力します。 次のコードをコピーし、[編集] メニューの [HTML として貼り付け] を選択して、ファイルのセクション <authentication> にコードを貼り付けます。

    <authentication mode="Forms">
        <forms name=".ASPXFORMSDEMO" loginUrl="logon.aspx"
            protection="All" path="/" timeout="30" />
    </authentication>
    
  4. セクション内の匿名ユーザーへのアクセスを次 <authorization> のように拒否します。

    <authorization>
        <deny users ="?" />
        <allow users = "*" />
    </authorization>
    

ユーザーの詳細を格納するサンプル データベース テーブルを作成する

このセクションでは、ユーザーのユーザー名、パスワード、および役割を格納するサンプル データベースを作成する方法を示します。 ユーザー ロールをデータベースに格納し、役割ベースのセキュリティを実装する場合は、役割列が必要です。

  1. [スタート]メニューの[ファイル名を 指定して実行] を選択し、メモ帳を入力してメモ帳。

  2. 次のスクリプト SQLを強調表示し、コードを右クリックし、[コピー] を 選択します。 [メモ帳編集]メニューの [貼 り付け]を選択 して、次のコードを貼り付けます。

    if exists (select * from sysobjects where id =
    object_id(N'[dbo].[Users]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
        drop table [dbo].[Users]
    GO
    CREATE TABLE [dbo].[Users] ([uname] [varchar] (15) NOT NULL,
        [Pwd] [varchar] (25) NOT NULL,
        [userRole] [varchar] (25) NOT NULL,
    ) ON [PRIMARY]
    GO
    ALTER TABLE [dbo].[Users] WITH NOCHECK ADD
        CONSTRAINT [PK_Users] PRIMARY KEY NONCLUSTERED
        ([uname]
        ) ON [PRIMARY]
    GO
    
    INSERT INTO Users values('user1','user1','Manager')
    INSERT INTO Users values('user2','user2','Admin')
    INSERT INTO Users values('user3','user3','User')
    GO
    
  3. ファイルを Users.sql として保存します

  4. コンピューターでSQL Serverクエリ アナライザーで Users.sql を開きます。 データベースの一覧から [pubs] を選択 し、スクリプトを実行します。 この操作では、サンプル ユーザー テーブルを作成し、このサンプル アプリケーションで使用する Pubs データベースにテーブルを設定します。

Logon.aspx ページの作成

  1. Logon.aspx という名前のプロジェクトに新 しい Web フォームを追加します

  2. エディターで Logon.aspx ページを開き、HTML ビューに切り替えます。

  3. 次のコードをコピーし、[編集] メニューの [HTML として貼り付け] オプションを使用して、タグの間にコードを挿入 <form> します。

    <h3>
        <font face="Verdana">Logon Page</font>
    </h3>
    <table>
        <tr>
            <td>Email:</td>
            <td><input id="txtUserName" type="text" runat="server"></td>
            <td><ASP:RequiredFieldValidator ControlToValidate="txtUserName"
                Display="Static" ErrorMessage="*" runat="server" 
                ID="vUserName" /></td>
        </tr>
        <tr>
            <td>Password:</td>
            <td><input id="txtUserPass" type="password" runat="server"></td>
            <td><ASP:RequiredFieldValidator ControlToValidate="txtUserPass"
            Display="Static" ErrorMessage="*" runat="server"
            ID="vUserPass" />
            </td>
        </tr>
        <tr>
            <td>Persistent Cookie:</td>
            <td><ASP:CheckBox id="chkPersistCookie" runat="server" autopostback="false" /></td>
            <td></td>
        </tr>
    </table>
    <input type="submit" Value="Logon" runat="server" ID="cmdLogin"><p></p>
    <asp:Label id="lblMsg" ForeColor="red" Font-Name="Verdana" Font-Size="10" runat="server" />
    

    この Web フォームは、ユーザーがアプリケーションにログオンするユーザー名とパスワードを提供できるよう、ログオン フォームをユーザーに提示するために使用されます。

  4. デザイン ビューに切り替えて、ページを保存します。

ユーザー資格情報を検証するイベント ハンドラーをコード化する

このセクションでは、(Logon.aspx.cs) の後ろのコード ページに配置されるコードを示します。

  1. [ログオン] をダブルクリック して Logon.aspx.cs ファイルを開 きます。

  2. 必要な名前空間をコード背後ファイルにインポートします。

    using System.Data.SqlClient;
    using System.Web.Security;
    
  3. データベースを ValidateUser 見て、ユーザー資格情報を検証する関数を作成します。 データベースをポイントする文字列 Connection を変更してください。

    private bool ValidateUser( string userName, string passWord )
    {
        SqlConnection conn;
        SqlCommand cmd;
        string lookupPassword = null;
    
        // Check for invalid userName.
        // userName must not be null and must be between 1 and 15 characters.
        if ( ( null == userName ) || ( 0 == userName.Length ) || ( userName.Length > 15 ))
        {
            System.Diagnostics.Trace.WriteLine( "[ValidateUser] Input validation of userName failed." );
            return false;
        }
    
        // Check for invalid passWord.
        // passWord must not be null and must be between 1 and 25 characters.
        if ( ( null == passWord ) || ( 0 == passWord.Length ) || ( passWord.Length > 25 ))
        {
            System.Diagnostics.Trace.WriteLine( "[ValidateUser] Input validation of passWord failed." );
            return false;
        }
    
        try
        {
            // Consult with your SQL Server administrator for an appropriate connection
            // string to use to connect to your local SQL Server.
            conn = new SqlConnection( "server=localhost;Integrated Security=SSPI;database=pubs" );
            conn.Open();
    
            // Create SqlCommand to select pwd field from users table given supplied userName.
            cmd = new SqlCommand( "Select pwd from users where uname=@userName", conn );
            cmd.Parameters.Add( "@userName", SqlDbType.VarChar, 25 );
            cmd.Parameters["@userName"].Value = userName;
    
            // Execute command and fetch pwd field into lookupPassword string.
            lookupPassword = (string) cmd.ExecuteScalar();
    
            // Cleanup command and connection objects.
            cmd.Dispose();
            conn.Dispose();
        }
        catch ( Exception ex )
        {
            // Add error handling here for debugging.
            // This error message should not be sent back to the caller.
            System.Diagnostics.Trace.WriteLine( "[ValidateUser] Exception " + ex.Message );
        }
    
        // If no password found, return false.
        if ( null == lookupPassword )
        {
            // You could write failed login attempts here to event log for additional security.
            return false;
        }
    
        // Compare lookupPassword and input passWord, using a case-sensitive comparison.
        return ( 0 == string.Compare( lookupPassword, passWord, false ));
    }
    
  4. 2 つの方法のいずれかを使用して、フォーム認証 Cookie を生成し、イベント内の適切なページにユーザーをリダイレクト cmdLogin_ServerClick できます。 サンプル コードは、両方のシナリオで提供されます。 要件に応じてどちらかを使用します。

    • メソッドを呼び出して、フォーム認証 Cookie を自動的に生成し、イベント内の適切な RedirectFromLoginPage ページにユーザーをリダイレクト cmdLogin_ServerClick します。

      private void cmdLogin_ServerClick(object sender, System.EventArgs e)
      {
          if (ValidateUser(txtUserName.Value,txtUserPass.Value))
              FormsAuthentication.RedirectFromLoginPage(txtUserName.Value, chkPersistCookie.Checked);
          else
              Response.Redirect("logon.aspx", true);
      }
      
    • 認証チケットを生成し、暗号化し、Cookie を作成し、応答に追加し、ユーザーをリダイレクトします。 この操作により、Cookie の作成方法を詳細に制御できます。 この場合は、カスタム データと共 FormsAuthenticationTicket に含めできます。

      private void cmdLogin_ServerClick(object sender, System.EventArgs e)
      {
          if (ValidateUser(txtUserName.Value,txtUserPass.Value))
          {
              FormsAuthenticationTicket tkt;
              string cookiestr;
              HttpCookie ck;
              tkt = new FormsAuthenticationTicket(1, txtUserName.Value, DateTime.Now,
              DateTime.Now.AddMinutes(30), chkPersistCookie.Checked, "your custom data");
              cookiestr = FormsAuthentication.Encrypt(tkt);
              ck = new HttpCookie(FormsAuthentication.FormsCookieName, cookiestr);
              if (chkPersistCookie.Checked)
                  ck.Expires=tkt.Expiration;
              ck.Path = FormsAuthentication.FormsCookiePath;
              Response.Cookies.Add(ck);
      
              string strRedirect;
              strRedirect = Request["ReturnUrl"];
              if (strRedirect==null)
                  strRedirect = "default.aspx";
              Response.Redirect(strRedirect, true);
          }
          else
              Response.Redirect("logon.aspx", true);
      }
      
  5. Web フォーム デザイナーが生成するコードで、次のコードがメソッド InitializeComponent に追加されます。

    this.cmdLogin.ServerClick += new System.EventHandler(this.cmdLogin_ServerClick);
    

Default.aspx ページの作成

このセクションでは、ユーザーが認証後にリダイレクトされるテスト ページを作成します。 ユーザーが最初にアプリケーションにログオンせずにこのページを参照すると、ユーザーはログオン ページにリダイレクトされます。

  1. 既存の WebForm1.aspx ページの名前を Default.aspx として変更し、エディターで開きます。

  2. HTML ビューに切り替えて、タグ間で次のコードをコピー <form> します。

    <input type="submit" Value="SignOut" runat="server" id="cmdSignOut">
    

    このボタンは、フォーム認証セッションからログオフするために使用されます。

  3. デザイン ビューに切り替えて、ページを保存します。

  4. 必要な名前空間をコード背後ファイルにインポートします。

    using System.Web.Security;
    
  5. [SignOut] をダブルクリックして、後ろのコード ページ (Default.aspx.cs) を開き、イベント ハンドラーで次のコード cmdSignOut_ServerClick をコピーします。

    private void cmdSignOut_ServerClick(object sender, System.EventArgs e)
    {
        FormsAuthentication.SignOut();
        Response.Redirect("logon.aspx", true);
    }
    
  6. Web フォーム デザイナーが生成するコードで、次のコードがメソッド InitializeComponent に追加されます。

    this.cmdSignOut.ServerClick += new System.EventHandler(this.cmdSignOut_ServerClick);
    
  7. プロジェクトを保存してコンパイルします。 これで、アプリケーションを使用できます。

備考

  • パスワードをデータベースに安全に保存する必要がある場合があります。 パスワードをデータベースまたは構成ファイルに格納する前に、名前の付いたクラス ユーティリティ関数 FormsAuthentication HashPasswordForStoringInConfigFile を使用してパスワードを暗号化できます。

  • 必要に応じて簡単に変更SQL構成ファイル (Web.config) に接続情報を保存できます。

  • 異なる組み合わせのパスワードを使用しようとするハッカーがログオンを防ぐためのコードの追加を検討できます。 たとえば、2 回または 3 回のログオン試行のみを受け入れるロジックを含めできます。 ユーザーが何らかの試みでログオンできない場合は、ユーザーが別のページにアクセスするか、サポートラインに電話してアカウントを再び有効にするまで、データベースにフラグを設定してログオンを許可しない場合があります。 また、必要に応じて適切なエラー処理を追加する必要があります。

  • ユーザーは認証 Cookie に基づいて識別されますので、このアプリケーションで Secure Sockets Layer (SSL) を使用して、誰も認証 Cookie や送信されるその他の貴重な情報を欺く可能性はありません。

  • フォーム ベースの認証では、クライアントがブラウザーで Cookie を受け入れるか有効にする必要があります。

  • 構成セクションの timeout パラメーターは、認証 Cookie が再生成される <authentication> 間隔を制御します。 パフォーマンスとセキュリティを向上させる値を選択できます。

  • インターネット上の特定の仲介プロキシとキャッシュは、ヘッダーを含む Web サーバー応答をキャッシュし、別のユーザー Set-Cookie に返される場合があります。 フォーム ベース認証では Cookie を使用してユーザーを認証します。この動作により、ユーザーが本来意図していない仲介プロキシまたはキャッシュから Cookie を受け取って、他のユーザーを誤って (または意図的に) 偽装する可能性があります。

関連情報