본문 바로가기
IT-개발,DB

[ASP.NET] ASP .NET에서 Active Directory 인증 또는 Forms 인증

by SB리치퍼슨 2009. 12. 8.

출처 : http://support.microsoft.com/kb/316748/ko

이 문서에서는 다음 Microsoft .NET Framework 클래스 라이브러리의 네임스페이스를 참조합니다.
  • System.Text
  • System.DirectoryServices
  • System.Security.Principal
  • System.Web.Security



요약

Visual C# .NET에서 ASP.NET 웹 응용 프로그램 만들기

Visual C# .NET FormsAuthAd 라는 새 ASP.NET 웹 응용 프로그램을 만들려면 다음과 같이 하십시오.

  1. Microsoft Visual Studio .NET 시작하십시오.
  2. 파일 메뉴에서 새로 만들기를 가리킨 다음 프로젝트 를 클릭하십시오.
  3. 프로젝트 형식Visual C# 프로젝트 클릭한 다음 템플릿 에서 ASP.NET 웹 응용 프로그램 을 누릅니다.
  4. 위치 상자에 WebApplication1을 함께 FormsAuthAd 대체하십시오.
  5. 확인 을 클릭하십시오.
  6. 솔루션 탐색기에서 참조 노드를 마우스 오른쪽 단추로 클릭한 다음 참조 추가 클릭하십시오.
  7. 참조 추가 대화 상자에서 .NET 탭의 System.DirectoryServices.dll, 선택 을 클릭한 다음 확인 을 누릅니다.

인증 코드 작성

LdapAuthentication.cs 라는 새 클래스 파일을 만들려면 다음과 같이 하십시오.

  1. 솔루션 탐색기에서 프로젝트 노드를 마우스 오른쪽 단추로, 추가 를 가리킨 다음 새 항목 추가 클릭하십시오.
  2. 클래스템플릿 에서 클릭하십시오.
  3. 이름 상자에 LdapAuthentication.cs 입력하고 열기 를 클릭하십시오.
  4. LdapAuthentication.cs 파일에서 기존 코드를 다음 코드로 바꿉니다.
    using System;
    using System.Text;
    using System.Collections;
    using System.DirectoryServices;
    
    namespace FormsAuth
    {	
      public class LdapAuthentication
      {
        private String _path;
        private String _filterAttribute;
    
        public LdapAuthentication(String path)
        {
          _path = path;
        }
    		
        public bool IsAuthenticated(String domain, String username, String pwd)
        {
          String domainAndUsername = domain + @"\" + username;
          DirectoryEntry entry = new DirectoryEntry(_path, domainAndUsername, pwd);
    			
          try
          {	//Bind to the native AdsObject to force authentication.			
             Object obj = entry.NativeObject;
    
    	DirectorySearcher search = new DirectorySearcher(entry);
    
    	search.Filter = "(SAMAccountName=" + username + ")";
    	search.PropertiesToLoad.Add("cn");
    	SearchResult result = search.FindOne();
    
    	if(null == result)
    	{
      	  return false;
    	}
    
    	//Update the new path to the user in the directory.
    	_path = result.Path;
    	_filterAttribute = (String)result.Properties["cn"][0];
          }
          catch (Exception ex)
          {
            throw new Exception("Error authenticating user. " + ex.Message);
          }
    
    	return true;
         }
    
         public String GetGroups()
         {
           DirectorySearcher search = new DirectorySearcher(_path);
           search.Filter = "(cn=" + _filterAttribute + ")";
           search.PropertiesToLoad.Add("memberOf");
           StringBuilder groupNames = new StringBuilder();
    
           try
           {
             SearchResult result = search.FindOne();
    
    	 int propertyCount = result.Properties["memberOf"].Count;
    
       	 String dn;
    	 int equalsIndex, commaIndex;
    				
    	 for(int propertyCounter = 0; propertyCounter < propertyCount; propertyCounter++)
    	 {
    	   dn = (String)result.Properties["memberOf"][propertyCounter];
    
        	   equalsIndex = dn.IndexOf("=", 1);
    	   commaIndex = dn.IndexOf(",", 1);
    	   if(-1 == equalsIndex)
    	   {
    	     return null;
         	   }
    
               groupNames.Append(dn.Substring((equalsIndex + 1), (commaIndex - equalsIndex) - 1));
    	   groupNames.Append("|");
    
        	 }
           }
           catch(Exception ex)
           {
             throw new Exception("Error obtaining group names. " + ex.Message);
           }			
           return groupNames.ToString();
         }
       }
    }
    					

인증 코드 도메인, 사용자 이름, 암호 및 Active Directory의 트리 경로를 입력할 수 있습니다. 이 코드는 LDAP 디렉터리 공급자를 사용합니다.

Logon.aspx 페이지에 코드 LdapAuthentication.IsAuthenticated 메서드 호출 및 사용자로부터 수집한 자격 증명을 전달합니다. 그런 다음 DirectoryEntry 개체는 디렉터리 트리, 사용자 이름 및 암호를 경로가 만들어집니다. 사용자 이름은 "도메인\사용자 이름" 형식이어야 합니다. DirectoryEntry 개체를 다음 NativeObject 속성을 가져오는 AdsObject 바인딩 강제로 시도합니다. 이 작업이 성공하면 사용자가 CN 특성 DirectorySearcher 개체 만들기 및 SAMAccountName에 대한 필터링을 얻을 수 있습니다. 사용자가 인증된 후에는 IsAuthenticated 메서드는 true 를 반환합니다.

사용자가 속한 그룹 목록을 얻으려면 이 코드 LdapAuthentication.GetGroups 메서드를 호출합니다. LdapAuthentication.GetGroups 메서드는 DirectorySearcher 개체 만들기 및 memberOf 특성을 따라 필터링을 사용자가 속한 보안 및 메일 그룹 목록을 가져옵니다. 이 메서드는 파이프 (|) 로 구분된 그룹 목록을 반환합니다.

LdapAuthentication.GetGroups 메서드는 조작하고 문자열을 잘라내는 알 수 있습니다. 인증 쿠키에 저장되는 문자열의 길이를 줄입니다. 문자열이 잘리지 각 그룹의 형식을 다음과 같이 나타납니다.

CN=...,...,DC=domain,DC=com
				

매우 긴 문자열을 만들 수 있습니다. 이 문자열의 길이가 쿠키의 길이보다 큰 경우 브라우저에서 인증 쿠키를 받아들일 수 및 로그온 페이지로 리디렉션됩니다. 그러나 다중 도메인 환경에 있는 경우 다른 도메인의 그룹을 동일한 그룹 이름을 가질 수 있으므로 그룹 이름 사용하여 도메인 이름을 유지해야 할 수 있습니다. 한 그룹에서 다른 구분하기 위해 도메인 이름을 유지해야 합니다.

대부분의 브라우저에서는 최대 4096바이트의 쿠키를 지원합니다. 이 문자열의 길이가 쿠키의 잠재적으로 초과할 수 있으면 그룹 정보를 ASP.NET 캐시 개체 또는 데이터베이스 저장할 할 수 있습니다. 또는 그룹 정보를 암호화하고 이 정보가 숨겨진된 폼 필드에 저장할 할 수 있습니다.

Global.asax 코드 작성

Global.asax 파일에 코드를 Application_AuthenticateRequest 이벤트 처리기를 제공합니다. 이 이벤트 처리기는 Context.Request.Cookies 컬렉션에서 인증 쿠키를 검색하고 해당 쿠키를 해독합니다 FormsAuthenticationTicket.UserData 속성에 저장된 그룹 목록을 검색합니다. 그룹은 Logon.aspx 페이지에 만들어지는 파이프 구분된 목록에 나타납니다.

코드를 GenericPrincipal 개체를 만들려면 문자열 배열의 문자열을 구문 분석합니다. GenericPrincipal 개체를 만든 후에는 이 개체의 HttpContext.User 속성은 배치됩니다.

  1. 솔루션 탐색기에서 Global.asax, 마우스 오른쪽 단추로 클릭한 다음 코드 보기를 클릭하십시오.
  2. 코드 숨김 Global.asax.cs 파일 맨 위에 다음 코드를 추가하여:
    using System.Web.Security;
    using System.Security.Principal;
    					
  3. 기존 빈 이벤트 처리기에 대한 Application_AuthenticateRequest 다음 코드로 대체합니다.
    void Application_AuthenticateRequest(Object sender, EventArgs e)
    {
      String cookieName = FormsAuthentication.FormsCookieName;
      HttpCookie authCookie = Context.Request.Cookies[cookieName];
    
      if(null == authCookie)
      {//There is no authentication cookie.
        return;
      }	
    		
      FormsAuthenticationTicket authTicket = null;
    	
      try
      {
        authTicket = FormsAuthentication.Decrypt(authCookie.Value);
      }
      catch(Exception ex)
      {
        //Write the exception to the Event Log.
        return;
      }
    	
      if(null == authTicket)
      {//Cookie failed to decrypt.
        return;		
      }		
    	
      //When the ticket was created, the UserData property was assigned a
      //pipe-delimited string of group names.
      String[] groups = authTicket.UserData.Split(new char[]{'|'});
    
      //Create an Identity.
      GenericIdentity id = new GenericIdentity(authTicket.Name, "LdapAuthentication");
    	
      //This principal flows throughout the request.
      GenericPrincipal principal = new GenericPrincipal(id, groups);
    
      Context.User = principal;
    	
    }
    					

Web.config 파일을 수정하십시오.

이 섹션에서는 다음 <forms>구성, <authentication>,, 및 해당 <authorization> Web.config 파일에서 요소를. 이러한 변경 내용이 인증된 사용자만 응용 프로그램에 액세스할 수 있으며 인증되지 않은 요청은 Logon.aspx 페이지로 리디렉션됩니다. 특정 사용자와 응용 프로그램이 그룹 액세스를 허용하도록 이 구성을 수정할 수 있습니다.

Web.config 파일에서 기존 코드를 다음 코드로 바꿉니다.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>    
  <system.web>
    <authentication mode="Forms">
      <forms loginUrl="logon.aspx" name="adAuthCookie" timeout="10" path="/" >
      </forms>
    </authentication>	
    <authorization>	
      <deny users="?" />
      <allow users="*" />
    </authorization>	
    <identity impersonate="true" />
  </system.web>
</configuration>
				

알 수 있는 <identity impersonate="true"/> 구성 요소. 이로 인해 ASP.NET에서 Microsoft 인터넷 정보 서비스 (IIS) 에서 익명 계정으로 구성할 계정을 가장할 수 있습니다. 이 구성은 이 응용 프로그램에 대한 모든 요청은 구성된 계정의 보안 컨텍스트에서 실행합니다. 사용자가 Active Directory에 [NULL]에 대해 인증 자격 증명을 제공하지만 Active Directory를 액세스하는 계정이 구성된 계정입니다. 자세한 내용은 References 섹션에.

익명 인증을 사용하도록 IIS를 구성하십시오.

익명 인증을 사용하도록 IIS를 구성하려면 다음 이 단계를 수행하십시오.

  1. IIS에서 서버의 컴퓨터 노드를 확장하고, 웹 사이트 를 확장한, 기본 웹 사이트 를 확장합니다. 그리고 FormsAuthAd, 마우스 오른쪽 단추로 클릭한 다음 속성 을 클릭하십시오.
  2. 디렉터리 보안 탭 을 클릭한 다음 익명 액세스 및 인증 제어에서편집 을 누릅니다.
  3. 응용 프로그램에 대한 익명 계정을 Active Directory 사용 권한을 가진 계정을 확인하십시오.
  4. 제어 암호 받는 IIS 허용 확인란의 선택을 취소하십시오.
  5. “ 인증된 액세스 ” 섹션에서 “ Windows 통합 인증 ” 확인란의 선택을 취소하십시오.
  6. 확인을 클릭하십시오.
  7. 적용을 클릭합니다.

기본 IUSR_ computername 계정은 Active Directory 권한이 없습니다.

Logon.aspx 페이지로 만들기

새 ASP.NET Web Form Logon.aspx 명명된 만들려면 다음과 같이 하십시오.

  1. 솔루션 탐색기에서 프로젝트 노드를 마우스 오른쪽 단추로, 추가 를 가리킨 다음 Web Form 추가 누릅니다.
  2. Logon.aspx이름 상자에 입력한 다음 열기 를 클릭하십시오.
  3. 솔루션 탐색기에서 Logon.aspx, 마우스 오른쪽 단추로 클릭한 다음 디자이너 보기를 클릭하십시오.
  4. 디자이너에서 HTML 탭을 클릭하십시오.
  5. Replace the existing code with the following code.
    <%@ Page language="c#" AutoEventWireup="true" %>
    <%@ Import Namespace="FormsAuth" %>
    <html>
      <body>	
        <form id="Login" method="post" runat="server">
          <asp:Label ID="Label1" Runat=server >Domain:</asp:Label>
          <asp:TextBox ID="txtDomain" Runat=server ></asp:TextBox><br>    
          <asp:Label ID="Label2" Runat=server >Username:</asp:Label>
          <asp:TextBox ID=txtUsername Runat=server ></asp:TextBox><br>
          <asp:Label ID="Label3" Runat=server >Password:</asp:Label>
          <asp:TextBox ID="txtPassword" Runat=server TextMode=Password></asp:TextBox><br>
          <asp:Button ID="btnLogin" Runat=server Text="Login" OnClick="Login_Click"></asp:Button><br>
          <asp:Label ID="errorLabel" Runat=server ForeColor=#ff3300></asp:Label><br>
          <asp:CheckBox ID=chkPersist Runat=server Text="Persist Cookie" />
        </form>	
      </body>
    </html>
    <script runat=server>
    void Login_Click(Object sender, EventArgs e)
    {
      String adPath = "LDAP://corp.com"; //Fully-qualified Domain Name
      LdapAuthentication adAuth = new LdapAuthentication(adPath);
      try
      {
        if(true == adAuth.IsAuthenticated(txtDomain.Text, txtUsername.Text, txtPassword.Text))
        {
          String groups = adAuth.GetGroups();
    
          //Create the ticket, and add the groups.
          bool isCookiePersistent = chkPersist.Checked;
          FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1,  txtUsername.Text,
    	DateTime.Now, DateTime.Now.AddMinutes(60), isCookiePersistent, groups);
    	
          //Encrypt the ticket.
          String encryptedTicket = FormsAuthentication.Encrypt(authTicket);
    		
          //Create a cookie, and then add the encrypted ticket to the cookie as data.
          HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
    
          if(true == isCookiePersistent)
    	authCookie.Expires = authTicket.Expiration;
    				
          //Add the cookie to the outgoing cookies collection.
          Response.Cookies.Add(authCookie);		
    
          //You can redirect now.
          Response.Redirect(FormsAuthentication.GetRedirectUrl(txtUsername.Text, false));
        }
        else
        {
          errorLabel.Text = "Authentication did not succeed. Check user name and password.";
        }
      }
      catch(Exception ex)
      {
        errorLabel.Text = "Error authenticating. " + ex.Message;
      }
    }
    </script>
  6. LDAP 디렉터리 서버를 가리키도록 Logon.aspx 페이지로 경로를 수정하십시오.

Logon.aspx 페이지로 사용자 및 호출 메서드를 LdapAuthentication 클래스에 대한 정보를 수집하는 페이지입니다. 코드의 사용자를 인증하고 그룹 목록을 가져오는 코드를 FormsAuthenticationTicket 개체를 만듭니다. 그리고 티켓을 암호화합니다. 그리고 암호화된 티켓을 데 쿠키를 추가합니다. 그리고 쿠키가 HttpResponse.Cookies 컬렉션에 추가합니다 후 다음 원래 요청된 URL로 요청을 리디렉션합니다.

WebForm1.aspx 페이지를 수정합니다

WebForm1.aspx 페이지를 처음 요청한 페이지입니다. 사용자가 이 페이지를 요청하면 Logon.aspx 위해 요청을 리디렉션할 페이지의. 요청이 인증된 후 요청은 WebForm1.aspx 페이지로 리디렉션됩니다.

  1. 솔루션 탐색기 에서 WebForm1.aspx 를 마우스 오른쪽 단추로 클릭한 다음 디자이너 보기를 클릭하십시오.
  2. 디자이너에서 HTML 탭을 클릭하십시오.
  3. 기존 코드를 다음 code.
    <%@ Page language="c#" AutoEventWireup="true" %>
    <%@ Import Namespace="System.Security.Principal" %>
    <html>
      <body>	
        <form id="Form1" method="post" runat="server">
          <asp:Label ID="lblName" Runat=server /><br>
          <asp:Label ID="lblAuthType" Runat=server />
        </form>	
      </body>
    </html>
    <script runat=server>
    void Page_Load(Object sender, EventArgs e)
    {
      lblName.Text = "Hello " + Context.User.Identity.Name + ".";
      lblAuthType.Text = "You were authenticated using " +   Context.User.Identity.AuthenticationType + ".";
    }
    </script>
    					
  4. 모든 파일을 저장하고 프로젝트를 컴파일하십시오.
  5. WebForm1.aspx 페이지를 요청하십시오. 알 수 Logon.aspx 리디렉션됩니다.
  6. 로그온 자격 증명을 입력한 다음 제출 을 클릭하십시오. WebForm1.aspx 위해 리디렉션할 때 사용자 이름이 나타나는지 확인합니다 및 LdapAuthentication 인증 있는지 Context.User.AuthenticationType 속성을 입력합니다.

참고 SSL (Secure Sockets Layer) 사용하는 것이 좋습니다 Forms 인증을 사용할 때 암호화. 인증 쿠키를 기반으로 사용자가 식별되기 때문에 이 응용 프로그램에 SSL 암호화를 누구나 인증 쿠키와 전송되는 기타 유용한 정보를 손상시키지 못하도록 방지할 수 있습니다.


----====  참조  ====----

자세한 내용은 Microsoft 기술 자료에 있는 문서를 보려면 다음 문서 번호를 클릭하시기 바랍니다:
306590  (http://support.microsoft.com/kb/306590/ ) ASP.NET 보안 개요
317012  (http://support.microsoft.com/kb/317012/ ) ASP.NET 에서 프로세스 및 요청 ID
311495  (http://support.microsoft.com/kb/311495/ ) Visual C# .NET을 사용하여 ASP.NET 응용 프로그램에서 폼 기반 인증 가진 역할 기반 보안을 구현하는 방법
313091  (http://support.microsoft.com/kb/313091/ ) Forms 인증 사용하기 위해 Visual Basic .NET을 사용하여 키를 만드는 방법
313116  (http://support.microsoft.com/kb/313116/ ) 폼 인증 요청은 loginUrl 페이지에 지정됩니다.

본 문서의 정보는 다음의 제품에 적용됩니다.
  • Microsoft Visual C# .NET 2003 Standard Edition
  • Microsoft Visual C# .NET 2002 Standard Edition
  • Microsoft ASP.NET 1.1


반응형

댓글