C#.NET을 사용하여 ASP.NET 애플리케이션에서 양식 기반 인증 구현

이 문서에서는 데이터베이스를 사용하여 사용자를 저장하여 양식 기반 인증을 구현하는 방법을 보여 줍니다. 다음 Microsoft .NET Framework 클래스 라이브러리 네임스페이스를 참조합니다.

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

원래 제품 버전: ASP.NET
원래 KB 번호: 301240

요구 사항

다음 목록에서는 필요한 권장 하드웨어, 소프트웨어, 네트워크 인프라 및 서비스 팩을 간략하게 설명합니다.

  • Visual Studio .NET
  • IIS(인터넷 정보 서비스) 버전 5.0 이상
  • SQL Server

C# .NET을 사용하여 ASP.NET 애플리케이션 만들기

  1. Visual Studio .NET을 엽니다.
  2. 새 ASP.NET 웹 애플리케이션을 만들고 이름과 위치를 지정합니다.

Web.config 파일에서 보안 설정 구성

이 섹션에서는 및 <authorization> 구성 섹션을 추가하고 수정 <authentication> 하여 양식 기반 인증을 사용하도록 ASP.NET 애플리케이션을 구성하는 방법을 보여 줍니다.

  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 프로젝트에 새 웹 양식을 추가합니다.

  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" />
    

    이 웹 양식은 사용자에게 로그온 양식을 제공하여 사용자 이름과 암호를 제공하여 애플리케이션에 로그온할 수 있도록 하는 데 사용됩니다.

  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. 두 가지 방법 중 하나를 사용하여 양식 인증 쿠키를 생성하고 이벤트의 적절한 페이지 cmdLogin_ServerClick 로 사용자를 리디렉션할 수 있습니다. 샘플 코드는 두 시나리오 모두에 대해 제공됩니다. 요구 사항에 따라 둘 중 하나를 사용합니다.

    • 메서드를 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);
      }
      
    • 인증 티켓을 생성하고, 암호화하고, 쿠키를 만들고, 응답에 추가하고, 사용자를 리디렉션합니다. 이 작업을 통해 쿠키를 만드는 방법을 더 자세히 제어할 수 있습니다. 이 경우 와 함께 사용자 지정 데이터를 포함할 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. 웹 양식 Designer 생성하는 코드의 메서드에 다음 코드가 추가 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. 웹 양식 Designer 생성하는 코드의 메서드에 다음 코드가 추가 InitializeComponent 되었는지 확인합니다.

    this.cmdSignOut.ServerClick += new System.EventHandler(this.cmdSignOut_ServerClick);
    
  7. 프로젝트를 저장하고 컴파일합니다. 이제 애플리케이션을 사용할 수 있습니다.

추가 참고 사항

  • 데이터베이스에 암호를 안전하게 저장할 수 있습니다. 라는 HashPasswordForStoringInConfigFile 클래스 유틸리티 함수를 FormsAuthentication 사용하여 암호를 데이터베이스 또는 구성 파일에 저장하기 전에 암호화할 수 있습니다.

  • 필요한 경우 쉽게 수정할 수 있도록 SQL 연결 정보를 구성 파일(Web.config)에 저장할 수 있습니다.

  • 다양한 암호 조합을 사용하려는 해커가 로그온하지 못하도록 코드를 추가하는 것이 좋습니다. 예를 들어 로그온 시도 2~3회만 허용하는 논리를 포함할 수 있습니다. 사용자가 일부 시도에서 로그온할 수 없는 경우 사용자가 다른 페이지를 방문하거나 지원 라인을 호출하여 계정을 다시 사용하도록 설정할 때까지 로그온할 수 없도록 데이터베이스에 플래그를 설정할 수 있습니다. 또한 필요한 경우 적절한 오류 처리를 추가해야 합니다.

  • 사용자가 인증 쿠키를 기반으로 식별되므로 아무도 인증 쿠키 및 전송되는 기타 중요한 정보를 속일 수 없도록 이 애플리케이션에서 SSL(Secure Sockets Layer)을 사용할 수 있습니다.

  • 양식 기반 인증을 사용하려면 클라이언트가 브라우저에서 쿠키를 수락하거나 사용하도록 설정해야 합니다.

  • 구성 섹션의 <authentication> 시간 제한 매개 변수는 인증 쿠키가 다시 생성되는 간격을 제어합니다. 더 나은 성능과 보안을 제공하는 값을 선택할 수 있습니다.

  • 인터넷의 특정 중간 프록시 및 캐시는 헤더를 포함하는 Set-Cookie 웹 서버 응답을 캐시할 수 있으며, 이 응답은 다른 사용자에게 반환됩니다. 양식 기반 인증은 쿠키를 사용하여 사용자를 인증하기 때문에 이 동작으로 인해 사용자가 원래 의도한 것이 아닌 중간 프록시 또는 캐시에서 쿠키를 수신하여 실수로 또는 의도적으로 다른 사용자를 가장할 수 있습니다.

참조