Silverlight를 설치하려면 여기를 클릭합니다.*
Korea 대한민국변경|Microsoft 전체 사이트
MSDN
|개발자 센터
MSDN Home   MSDN Home

필요한 대상

새로운 ASP.NET 2.0 멤버 API를 사용한 사이트 인증 업그레이드


 and 
이 기사의 일부는 ASP.NET 2.0 시험판 버전을 기반으로 합니다. 여기에 기록된 내용은 변경될 수 있습니다.

이 문서 내용:
  • ASP.NET 응용 프로그램을 위한 일반적인 인증 기술
  • ASP.NET 2.0의 멤버 API 및 공급자 모델
  • 역할 기반 보안 및 권한 부여
이 문서에는 다음 기술이 사용됩니다:
ASP.NET, Visual Basic


Code download available at:
Membership.exe (148KB)

첫 번째 릴리스에서 ASP.NET은 폼 인증을 도입했습니다. 폼 인증에서는 손쉽게 사용할 수 있는 API로 안전하게 사용자 인증을 처리하는 강력한 프레임워크를 제공했습니다. 폼 인증의 핵심은 ASP.NET 2.0에서도 변경되지 않았으므로 대부분의 방법과 기술은 계속 사용할 수 있습니다. 그러나 ASP.NET 2.0에서는 많은 사항이 개선되어 사용자 인증 및 관리를 위한 강력한 시스템을 더욱 쉽게 구축할 수 있는 새로운 멤버 자격 시스템을 제공합니다. 새로운 멤버 자격 시스템의 기반이 되는 공급자 모델의 기본 내용 및 공급자 모델과 폼 인증 간의 긴밀한 통합을 검토하다 보면 반드시 '이 새로운 멤버 자격 시스템이 기존 코드와 사용자 및 역할 데이터베이스에 주는 영향'에 대한 의문이 들 것입니다.

언뜻 보면 ASP.NET 2.0의 완전 자동 인증 메커니즘은 암호와 역할 관리 코드 등 기존의 ASP.NET 1.x 유효성 검사 코드를 다시 작성하는 경우에만 작동하는 것처럼 보입니다. 또한 ASP.NET 2.0에서는 사용자 데이터베이스를 미리 정의된 SQL Server™ 또는 Active Directory® 체계에 따르도록 변경해야 하는 것으로 보입니다. 그러나 이것은 오해입니다.

ASP.NET 2.0 인증의 핵심은 새로운 멤버 API(사용자 인증을 위한 공용 제네릭 API)와 공급자 모델(인증을 실현하는 기본 사양)입니다. ASP.NET 2.0에서 인증은 공급자 기반의 확장 가능한 모델 위에 구축됩니다. 이런 방법을 사용하면 멤버 자격 시스템과 상호 작용하는 코드를 수정하지 않고도 기본 유효성 검사 코드 및 사용자 관리를 쉽게 변경할 수 있습니다. 따라서 기존의 코드를 ASP.NET 2.0의 인증 방법에 연결하도록 쉽게 개조할 수 있습니다.

여기서는 플러그형 공급자에 기초하여 멤버 API의 연결과 기본적으로 확장 가능한 특성을 다룰 것입니다. 또한 기존의 ASP.NET 1.x 인증 메커니즘을 가져와 ASP.NET 2.0으로 이식하여 새 멤버 API를 통해 레거시 인증 메커니즘을 구현할 것입니다. 여러분이 작성해야 하는 코드는 아주 적으며 예상보다 재사용 정도가 높습니다.


ASP.NET 인증

ASP.NET 1.x에서 폼 인증을 구현하려면 여러 단계의 절차를 거쳐야 합니다. 먼저 응용 프로그램의 Web.config 파일에서 <authentication> 섹션을 조정하여 폼 기반 인증을 등록합니다. 그런 다음 요청하는 사용자에게 표시될 로그인 페이지를 작성합니다. 마지막으로 인증 전략을 계획하고 필요한 저장소를 설정하며 필수 코드를 구현해야 합니다. 다음 내용을 Web.config 파일에 삽입하면 올바른 인증 티켓이 없는 페이지 요청은 login.aspx로 리디렉션됩니다.

<authentication mode="Forms">
   <forms loginUrl="login.aspx" protection="All" />
</authentication>
<authorization>
   <deny users="?"/>
</authorization>

특수 HTTP 모듈인 FormsAuthenticationModule은 이러한 확인 작업을 담당합니다. 이 모듈은 두 파이프라인 이벤트 AuthenticateRequest 및 EndRequest를 연결합니다. 요청을 받고 인증 준비가 완료되면 모듈은 사용자의 자격 증명이 포함된 인증 티켓을 찾습니다. 인증 티켓은 구성 가능한 이름(기본값: .ASPXAUTH)이 있는 암호화된 HTTP 쿠키입니다. 올바른 티켓이 없으면 요청은 지정된 로그인 페이지로 리디렉션되며 이 페이지의 URL은 구성 파일에서 읽어들입니다. 쿠기를 사용하지 않고 이 프로세스를 구현하는 자세한 방법은 관련 기사 "쿠키를 사용하지 않는 인증"을 참조하십시오.

로그인 페이지는 최소한 두 개의 텍스트 상자와 하나의 전송 단추가 포함된 Web Form입니다. 로그인 페이지에 대한 미리 정의된 템플릿 또는 필수 레이아웃은 없으며 각 응용 프로그램은 해당 요구에 가장 적합한 로그인 페이지를 제공할 수 있습니다. 그러나 하나의 필수 요소는 postback 이벤트에 바인딩된 코드이며, 대개 Button 또는 LinkButton의 Click 이벤트입니다. 이 이벤트는 사용자 자격 증명(선택된 "사용자 이름 및 암호 저장" 확인란과 같은 다른 사용 가능한 데이터 포함)을 수집한 다음 사용자 데이터베이스에서 이 정보의 유효성을 검사합니다.

그림 1은 일반적인 ASP.NET 1.x 코드를 보여 줍니다. 그 핵심에 AuthenticateUser 사용자 지정 메서드가 있습니다. 이 메서드는 사용자 이름 및 암호를 받은 후 사용자 데이터베이스에 대해 쿼리를 실행하여 해당 이름 및 암호가 올바른 계정을 나타내는지 확인합니다.

이런 종류의 코드는 매우 흔하지만 가장 중요한 사실은 잘 작동한다는 것입니다. 따라서 문제가 될 것이 없습니다. 기존의 응용 프로그램을 업그레이드하는 경우 ASP.NET 2.0의 시간이 절약되는 새 기능을 무시하거나 다른 데이터베이스(대개는 SQL Server) 및 스키마를 다루기 위해 대부분의 기존 코드를 버리고 다시 작성할 수도 있습니다. 그러나 복잡할 수밖에 없는 응용 프로그램을 사용하는 경우 자격 증명을 확인하는 간단한 코드 외에 더 많은 내용을 다루어야 합니다. 그 대신 사용자 관리자 개체, 전자 메일 및 역할 관리, 암호 미리 알림 및 재설정을 위한 질문/응답 프로토콜, 암호 정책 등을 포함할 수 있습니다.

ASP.NET 2.0 프로그래밍 스타일을 준수해야 하는 것은 기능상의 문제 때문이 아닙니다. 작동 중인 구형 코드를 다시 컴파일하거나 최신 ASP.NET 2.0 구성 요소를 수용하거나 사용자 인증을 위한 시스템의 실제 동작은 변하지 않습니다. 그러나 ASP.NET 2.0 모델을 사용하면 새로운 컨트롤과 멤버 자격부터 역할과 암호 관리에 이르는 새로운 맞춤형 API 등을 활용할 수 있습니다. 보안 관련 컨트롤 집합(관련 기사 "ASP.NET 2.0의 보안 컨트롤") 참조)을 사용하면 로그인/로그아웃 기능을 간단하게 작성할 수 있습니다. 사용자가 로그인 및 로그아웃을 수행하고 로그인 상태를 표시하며 암호를 변경하고 미리 알림을 가져오고 새 사용자 계정을 만들 수 있도록 하는 미리 만든 GUI 컨트롤을 사용할 수 있습니다. 이러한 기능은 단순히 부차적인 것이 아니라 거의 모든 웹 응용 프로그램에서 요구하는 공통적인 기능입니다.

그림 2 ASP.NET 2.0 구성 도구
그림 2 ASP.NET 2.0 구성 도구

또한 대부분의 응용 프로그램에는 관리자가 사용자, 암호 및 역할을 만들고 관리할 수 있는 백 엔드 시스템이 필요합니다. ASP.NET 2.0에서는 UI 관련 작업을 위한 새로운 컨트롤인 IDE 구성 도구(그림 2 참조)와 멤버 자격 및 역할 관리 함수를 호출하기 위한 확장 가능한 공통 API를 제공합니다.


멤버 API의 시드

사용자가 지정할 수 있는 공통 함수에 대한 확장 가능 공통 API의 실제 부가 가치를 이해하려면 최근 논란의 대상이 되고 있는 ASP.NET 1.x의 보안 관련 기능인 Web.config 파일 내 암호 저장 기능을 자세히 살펴 보십시오. 엔터프라이즈 개발자가 다음과 같이 사용자 정보를 저장하는 문제를 진지하게 고려한다는 것은 의심스러운 일입니다. 더구나 암호를 Web.config 파일에 일반 텍스트로 저장하는 경우는 더욱 그렇습니다.

<authentication mode="Forms">
   <forms loginUrl="login.aspx" protection="All">
      <credentials passwordFormat="SHA1">
         <user name="Joe" password="07B7F3EE06F278D" />
         <user name="Bob" password="B966BE960E7CBBD" />
      </credentials>
   </forms>
</authentication>
따라서 ASP.NET에서 사용자 자격 증명을 구성 파일에 저장하도록 허용하는 것을 이상하게 생각할 수도 있습니다. 어쨌든 그 과정에서 ASP.NET 인증 방법으로 사용자 데이터를 쿼리할 수 있게 됩니다. Web.config에 저장된 자격 증명이 있는 경우 로그인 페이지에서 실행되는 다음 코드는 매우 훌륭하게 작동합니다.
If FormsAuthentication.Authenticate(user, password) Then
   FormsAuthentication.RedirectFromLoginPage(user, false)
Else
   errorMsg.Text = "Sorry, that's not it."
End If

이 코드는 작지만 필수적인 세부 사항 하나가 그림 1과는 다릅니다. 사용자 인증 작업은 Authenticate 메서드로 위임되며 이 메서드는 System.Web 어셈블리에서 사용할 수 있는 FormsAuthentication 클래스에 정적으로 정의됩니다.

이 기능은 보통 두 가지 방식으로 생각할 수 있습니다. Authenticate 메서드는 XML 파일에 저장된 사용자 이름을 확인하기 위해 기본으로 제공되며 그다지 유용하지 않은 바로 가기로 생각할 수 있습니다. 아니면 좀 더 깊게 생각하여 Authenticate 메서드를 시스템 기능의 변경할 수 없는 공용 인터페이스로 간주할 수도 있습니다. 변경할 수 없는 인터페이스를 사용하면 완전히 자동화되고 코드가 없는 선언적 방식으로 페이지 및 기타 컨트롤과 상호 작용하는 시각적 구성 요소를 작성할 수 있습니다.

ASP.NET 1.x의 방식으로 로그인 컨트롤을 어떻게 설계하시겠습니까? 인증은 어떻게 처리하시겠습니까? 가장 간단한 방법은 제출 단추의 Click 이벤트를 사용자 정의 이벤트에 바인딩하는 것일 수 있습니다. 페이지 작성자는 이벤트를 처리하고 전달된 자격 증명을 확인한 다음 true 또는 false를 반환합니다. 이 모델은 작동은 하지만 페이지 및 로그인 폼 간의 긴밀한 결합이 필요하고 일부 코드를 작성해야 합니다. 사용자는 변경할 수 없는 공용 인터페이스를 사용하여 인증 프로세스를 트리거하기 때문에 앞에서 언급한 대부분의 코드를 로그인 구성 요소에 포함시킬 수 있습니다. 로그인 구성 요소를 사용하는 결과 페이지는 코드 없는 페이지가 됩니다. 물론 이 패턴은 로그인 기능 이상으로 확장하여 사용할 수 있습니다.


멤버 자격을 사용한 인증 사용자 지정

일반적으로 고정된 공용 API는 알려진 고정된 동작으로서 전략 및 기본 알고리즘을 의미합니다. 예를 들어 인증은 자격 증명을 확인하는 것입니다. 그러나 모든 응용 프로그램에는 자격 증명을 확인하는 자체적인 방식이 있으며, 이는 다양한 데이터베이스, 다양한 스키마, 다양한 저장 프로시저 등을 통해 이루어집니다. 보시다시피 하나의 전략은 다양한 알고리즘을 통해 구현할 수 있습니다.

그림 3 1.x 체계
그림 3 1.x 체계

ASP.NET 1.x에서 Authenticate 메서드는 알려진 전략을 적용하기 위한 고정된 공용 API를 나타내지만 인증(실제 알고리즘) 방식을 사용자 지정하는 교환 가능한 구성 요소를 지원할 만큼 지능적으로 구현되지는 않습니다. ASP.NET 2.0에서 멤버 API는 사용자 인증 및 관리와 연관된 여러 작업을 수행합니다. ASP.NET 1.x에서 사용되는 Authenticate 메서드와는 달리, 멤버 API는 ASP.NET 2.0 공급자 모델을 지원하므로 지정된 기능을 사용자 고유의 방식으로 구현할 수 있습니다. 그림 3은 ASP.NET 1.x의 멤버 자격 체계를 보여 주며 그림 4 는 ASP.NET 2.0의 동일한 스키마를 보여 줍니다. 사용자 지정 구성 요소(멤버 자격 공급자)를 작성 및 등록하면 공용 멤버 API에서 사용자 지정 메서드(기본 메서드와 반대)를 사용하여 인증 작업을 수행하도록 지시할 수 있습니다. 이 모델을 통해 지정된 기능(이 경우에는 사용자 인증)의 기본 구현을 무시하고 직접 작성한 구현을 사용할 수 있습니다.

그림 4 2.0 체계
그림 4 2.0 체계

여러분이 소프트웨어 순수론자이거나 단지 공식적인 용어를 좋아하는 경우 이 개념은 매우 친숙하게 느껴질 것입니다. 이 개념은 전략 패턴의 인스턴스일 뿐입니다. 전략 패턴은 교환 가능한 다양한 알고리즘(예: 빠른 정렬 또는 병합 정렬)을 통해 구현할 수 있는 예상된 동작(예: 정렬)을 나타냅니다. 그러면 각 응용 프로그램은 가장 적합한 알고리즘을 선택합니다. ASP.NET 멤버 자격과 관련하여 멤버 자격 공급자는 Active Directory, SQL Server 데이터베이스 또는 Oracle 데이터베이스 등의 사용자 지정 알고리즘에 기초하여 예상된 동작을 구현합니다.

Web.config 파일에 멤버 자격 공급자를 등록하면 해당 응용 프로그램에서 컴파일 시 실제로 인식하지 못하는 개체의 인스턴스를 작성합니다. 이 모델을 팩터리 패턴이라고 합니다.


멤버 API 사용

ASP.NET 2.0의 새로운 Membership 클래스를 사용하면 사용자 인증을 위해 작성해야 하는 코드 양을 줄일 수 있으며 역할 관리를 위한 기본 제공 인프라를 구성할 수 있습니다. Membership 하위 시스템의 기능을 사용하면 다음과 같이 사용자 인증 코드를 다시 작성할 수 있습니다.

Sub Logon_Click(sender As Object, e As EventArgs) 
   Dim user As String = userName.Text
   Dim password As String = passWord.Text
   If (Membership.ValidateUser(user, password))
      FormsAuthentication.RedirectFromLoginPage(user, false)
   Else
      errorMsg.Text = "Sorry, that's not it."
   End If
End Sub
이 코드는 ASP.NET 1.x 응용 프로그램에서 작성하는 코드와 거의 동일하며 다만 FormsAuthentication.Authenticate 정적 메서드 대신 Membership.ValidateUser 정적 메서드를 사용한다는 차이점이 있습니다. ValidateUser의 실제 동작은 사용이 등록된 데이터 공급자에서 결정합니다. 모든 공급자는 여러 멤버 자격 관련 작업을 충분히 통합할 수 있는 표준 인터페이스를 노출해야 합니다. ValidateUser는 이러한 API에 래퍼를 제공하며 사용 중인 공급자에 관계 없이 해당 응용 프로그램에서 사용할 수 있는 단일 메서드를 노출합니다. 사용해야 할 공급자는 응용 프로그램의 Web.config 파일에 등록됩니다. 공급자를 변경하고 그 후에 인증 엔진을 변경할 수도 있습니다. 이때 응용 프로그램을 다시 컴파일할 필요가 없으며 멤버 API를 이용하는 페이지에서 어떤 코드도 변경할 필요가 없습니다.

SQL Server, 저장 프로시저, 암호화 등의 데이터 저장 도구 및 메커니즘에 대해 자세히 몰라도 ASP.NET 2.0의 멤버 자격 기능을 사용할 수 있습니다. 멤버 API는 수많은 구성 옵션을 제공하지만 자격 증명을 저장하고 확인하는 방식에 관한 다양한 세부 사항은 사용자에게 알리지 않습니다. Membership 클래스에는 연결된 각 사용자의 고유 ID를 가져오는 데 사용되는 몇몇 정적 속성 및 메서드가 포함되어 있습니다. 또한 이 사용자 정보는 역할 기반 기능 및 개인 설정 기능을 포함하여 다른 ASP.NET 서비스와 함께 사용될 수 있습니다.

그림 5는 Membership 클래스에서 사용할 수 있는 다양한 속성을 설명합니다. 이 속성들은 매우 간단하게 구현되는 정적 속성이며 각 속성은 현재의 공급자에서 상응하는 멤버에 간단히 액세스합니다.

이름에서 짐작할 수 있듯이 Initialize 메서드는 Membership 클래스가 Web.config 파일의 설정으로 올바르게 구성되고 조정되도록 합니다. Provider 속성은 현재 사용 중인 멤버 자격 공급자에 대한 참조를 반환합니다. 그런 다음 Initialize 메서드 및 Provider 속성은 여러 공용 정적 속성에서 내부적으로 사용됩니다. 예를 들어 사용자가 Membership.PasswordAttemptWindow에 액세스할 때 먼저 Initialize가 호출되어 구성이 완료되었는지 확인된 다음 PasswordAttemptWindow 속성이 현재의 공급자에게 위임됩니다.

Public Shared ReadOnly Property PasswordAttemptWindow As Integer
  Get
     Membership.Initialize()
     Return Membership.Provider.PasswordAttemptWindow
  End Get
End Property

ASP.NET 2.0 베타 2 버전은 Active Directory를 대상으로 하는 미리 정의된 공급자(System.Web.Security.ActiveDirectoryMembershipProvider) 및 SQL Server 데이터베이스 및 SQL Server Express의 MDF 파일을 대상으로 하는 다른 공급자(System.Web.Security.SqlMembershipProvider)와 함께 제공됩니다. 베타 1의 Microsoft® Access용 공급자는 ASP.NET 2.0에 포함되지 않지만 나중에 샘플 소스 코드로서 다시 제공될 수도 있습니다. 등록된 공급자 목록은 Providers 컬렉션을 통해 얻을 수 있습니다. 일부 속성은 공급자에 따라 다르며 특정 공급자에서는 지원되지 않을 수도 있습니다. 물론 공급자는 이 기사에서 설명한 것보다 더 많은 속성을 구현할 수 있습니다.

그림 6에는 사용자 만들기, 업데이트 및 삭제를 위한 메서드를 포함하여 Membership 클래스의 메서드 목록이 있습니다. 일부 메서드는 MembershipUser 개체를 반환하거나 승인하며 이 개체에는 사용자와 관련하여 시스템에 저장된 정보가 포함되어 있습니다. 기존의 데이터베이스와 같은 사용자 지정 데이터 저장소를 사용하려면 직접 공급자를 작성하여 해당 데이터 저장소를 멤버 API를 사용하는 모든 응용 프로그램에서 액세스할 수 있도록 합니다. 또한 하나의 응용 프로그램에 여러 공급자를 등록할 수 있습니다. 이 경우 해당 응용 프로그램은 런타임에 적절한 공급자를 선택할 수 있습니다.

사용자 및 암호를 오프라인으로 관리할 경우 일반적으로 웹 사이트 관리 도구(그림 2 참조)를 사용합니다. 그러나 새로운 사용자를 프로그래밍 방식으로 생성하려면 CreateUser 메서드를 호출해야 합니다. 등록된 사용자의 로그인을 위한 패널과 새 사용자의 새 계정 등록을 위한 패널 등 상호 배타적인 두 개의 패널을 갖는 로그인 페이지가 있다고 가정해 봅시다(그림 7 참조).

그림 7 별개의 로그인 페이지
그림 7 별개의 로그인 페이지

새 사용자 등록을 허용하는 링크를 클릭하면 페이지는 패널을 전환하고 새 사용자의 이름 및 암호를 수집하는 입력 폼을 표시합니다. 추가 단추의 click 처리기는 다음 코드를 실행합니다.

Sub AddNewUser_Click(sender As Object, e As EventArgs)
  Membership.CreateUser(NewUserName.Text, NewUserPassword.Text)
  NewUserPanel.Visible = False
  LogUserPanel.Visible = True
End Sub

이 예에서 사용된 CreateUser의 오버로드는 실제로 기본 멤버 자격 구성과 함께 작동하지 않습니다. 기본 구성을 사용하면 암호 기반 재설정을 수행할 수 있지만 이 작업에는 질문 및 응답이 필요합니다. 그 결과 기본 멤버 자격 구성을 사용할 경우 다른 오버로드 중 하나를 사용해야 합니다.

사용자를 삭제하려면 삭제될 사용자의 등록된 사용자 이름을 받아들이는 DeleteUser 메서드를 다음과 같이 사용합니다.

Membership.DeleteUser(userName)
GetUser 메서드를 사용하면 특정 사용자의 정보를 매우 쉽게 검색할 수 있습니다. 이 메서드는 사용자 이름을 가져와 MembershipUser 개체를 반환합니다.
MembershipUser user = Membership.GetUser("AndreaS")

일단 MembershipUser 개체를 가져오면 특정 사용자에 관해 필요한 내용을 모두 알게 되며 암호를 프로그래밍 방식으로 변경할 수 있습니다. 응용 프로그램은 흔히 암호에 관해 변경 또는 재설정, 사용자에게 전송하기(질문/응답 챌린지 프로토콜 사용) 등과 같은 여러 작업을 지원해야 합니다. 이러한 기능은 멤버 API에서 모두 지원하지만 기본 공급자에서 반드시 지원하는 것은 아닙니다. 공급자에서 주어진 기능을 지원하지 않는 경우 메서드가 호출될 때 예외가 Throw됩니다.

ChangePassword 메서드를 사용하려면 새 암호 외에 이전의 암호도 제공해야 합니다.

   Dim user As MembershipUser = Membership.GetUser("AndreaS")
   user.ChangePassword(user.GetPassword(), newPassword)
그러나 이 방법은 특정 상황에서는 작동하지 않을 수도 있습니다. 예를 들어 일반적인 보안 방법인 해시되거나 솔트된(salted) 데이터베이스에 암호를 저장하도록 멤버 자격 시스템을 구성한 경우가 그렇습니다. 이 경우에 원래의 암호는 검색될 수 없으며 사용자가 현재의 암호를 잊은 경우 유일하게 사용할 수 있는 옵션은 암호 재설정뿐입니다. 암호를 재설정하려면 다음과 같이 ResetPassword 메서드를 사용합니다.
Dim user As MembershipUser = Membership.GetUser("AndreaS")
string newPassword = user.ResetPassword()

ResetPassword를 호출하는 응용 프로그램의 하위 시스템도 예를 들면 전자 메일을 통해 새 암호를 사용자에게 보내는 작업을 담당합니다. GetPassword 및 ResetPassword 메서드에는 모두 문자열 매개 변수를 사용하는 두 번째 오버로드가 있습니다. 지정된 문자열은 사용자의 "암호 분실" 질문에 대한 답을 나타냅니다.

암호 챌린지 지원뿐만 아니라 암호 재설정 기능도 공급자에 따라 다르며 Web.config 파일에서 구성됩니다. 암호 챌린지 질문은 MembershipUser 클래스의 읽기/쓰기 멤버로서 노출됩니다. 사용자를 만들 때 챌린지 질문 및 응답을 설정하고 멤버 자격 데이터베이스에 저장해야 합니다.


사용자 지정 공급자 작성

SQL Server Express 데이터베이스 파일에 멤버 자격 데이터를 저장하는 것과 ASP.NET에서 채택한 표준 스키마에 만족하는 경우 웹 사이트 관리 도구를 사용하여 현재 응용 프로그램에 대한 데이터베이스를 만들고 채우는 것 외에는 크게 할 일이 없습니다. 그러나 사용자 지정 스키마로서 Oracle 데이터베이스 또는 SQL Server 데이터베이스를 사용하려고 할 경우 얘기가 달라집니다. 또는, 좀 더 중요한 문제로서, 현재의 ASP.NET 1.x 응용 프로그램에 대한 전체 멤버 자격 시스템을 구축하는 데 시간과 비용을 투자한 경우는 어떻겠습니까? 걱정할 필요는 없습니다. 사용자 지정 멤버 자격 공급자를 작성할 예정이고 작성할 수 있는 능력이 있으면 이 코드의 전체나 일부를 다시 사용할 수 있습니다.

ASP.NET 2.0에서 사용된 모든 공급자는 ProviderBase 추상 클래스로 정의한 공통 멤버 집합을 구현합니다. 클래스는 하나의 가상 메서드(Initialize) 및 두 개의 가상 속성(Name 및 Description)과 함께 사용됩니다. Name 속성은 공급자 클래스의 정식 이름을 반환합니다. Initialize 메서드는 공급자의 이름 및 공급자의 구성 섹션의 내용으로 채워진 이름/값 컬렉션 개체를 가져옵니다. 여러 추상 클래스는 ProviderBase에서 파생되며 MembershipProvider, RoleProvider 등을 포함하여 다양한 특정 공급자 작업에 대한 기본 클래스로 작동합니다. MembershipProvider는 몇몇 추상 메서드로 구성되므로 직접적으로 사용할 수 없습니다. 사용자 지정 멤버 자격 공급자를 작성하려면 MembershipProvider를 상속합니다. 그림 8은 재정의할 가상 속성 및 메서드의 목록을 보여 줍니다.

그림 9는 매우 간단하지만 유용한 샘플 클래스를 보여 줍니다. 이 샘플 클래스는 그림 1에서 ASP.NET 1.x 응용 프로그램에 대해 사용된 인증 코드를 통합합니다. 보시다시피 대부분의 메서드 및 속성에는 예외만 발생시키는 null 구현이 있습니다. 그러나 ValidateUser에 대한 구현은 ASP.NET 1.x 응용 프로그램에서 가져온 일부 코드 안으로 콜백합니다. 더 많은 기능을 사용할수록 보다 의미 있는 방식으로 다른 메서드 및 속성을 재정의하는 방법으로 더 많은 항목을 ASP.NET 2.0으로 이식할 수 있습니다. 예를 들어 기존 코드에 사용자에 대한 CRUD(만들기/읽기/업데이트/삭제) 작업을 수행할 사용자 관리자 개체가 포함된 경우 해당 멤버를 사용자 지정 멤버 자격 공급자의 메서드에 쉽게 매핑할 수 있습니다. MSDN®Magazine 웹 사이트에서 다운로드할 수 있는 이 기사의 추가 코드는 그러한 기능을 ASP.NET 2.0으로 이식하는 방법을 보여 줍니다.

새로운 멤버 자격 공급자를 등록하려면 다음과 같이 Web.config 파일을 조정해야 합니다.

<membership defaultProvider="MyMembershipProvider">
   <providers>
     <add name="MyMembershipProvider" 
          type="MsdnMag.MyMembershipProvider" />
   </providers>
</membership>
이 코드를 응용 프로그램의 Web.config 파일에서 <system.web> 노드 아래에 추가하기만 하면 됩니다. 이제부터 Membership 클래스에 대한 모든 호출은 해당 공급자 클래스의 메서드 안으로 호출되면서 확인됩니다. 그림 10은 새 공급자를 선택하는 데 사용되는 웹 사이트 관리 도구를 보여 줍니다.

그림 10 새로운 멤버 자격 공급자 관리
그림 10 새로운 멤버 자격 공급자 관리

어댑터 패턴

이제 ASP.NET 1.x 멤버 자격 코드는 ASP.NET 2.0 응용 프로그램에 맞게 변경되고 재사용될 수 있다는 사실을 확인했습니다. 기존의 인증 엔진이 아무리 복잡하더라도 대부분을 재사용하고 이러한 부분들을 새롭고 뛰어난 ASP.NET 2.0 보안 및 인증 인프라로 통합할 수 있는 방법은 항상 존재하기 마련입니다. 이러한 결과를 이루는 데 필수적인 다른 보편적인 설계 패턴으로 어댑터 패턴이 있습니다.

어댑터 패턴은 특정 클래스 A의 프로그래밍 인터페이스를 특정 클라이언트 클래스 C가 완전히 이해하는 인터페이스 B로 변환합니다. 즉, 어댑터 패턴은 다른 클래스의 구현을 래핑하고 이 두 번째 클래스를 다른 인터페이스를 통해 노출하는 클래스를 지정합니다. 이러한 컨텍스트에서 어댑터 패턴의 가장 흥미로운 특성은 자체의 내부 구현에 대한 액세스를 허용하는 방법을 멤버 자격 공급자 클래스에 제공(기존의 ASP.NET 1.x 코드에 기초)한다는 점이며 이 경우 호출자(예: ASP.NET 2.0 로그인 페이지 또는 보안 컨트롤)가 해당 구현의 사양으로 바인딩되지 않는 방식이 사용됩니다.

보조 노트를 보면, 어댑터 패턴은 상속에 의존하지 않고 클래스에서 일부 기능을 재사용하는 데 활용될 수도 있습니다. 패턴 설계(Addison-Wesley, 1995)의 Erich Gamma씨와 공동 저자의 설명을 쉽게 바꿔 말하자면 항상 상속보다는 개체 구성을 선호해야 한다는 것입니다. 상속은 기존의 형식을 특수화하여 다형성을 활용하는 방식으로 주로 사용되어야 합니다. 이것은 기존의 코드를 재사용하는 전략과는 반대입니다. 더욱이 .NET Framework과 같은 단일 상속 환경에서 이 패턴을 사용하면 다른 상황에 대한 기본 클래스를 저장할 수 있으므로 이 패턴은 더욱 중요해집니다.

현재 자신의 ASP.NET 1.x 코드를 더 효과적으로 구성할 수 있으면 어댑터 패턴을 적용하는 작업은 더 쉬워집니다. 모든 논리 및 데이터를 클래스 집합 안으로 래핑하는 것은 유일하게 도움이 됩니다. 최소한, 예상되는 모든 속성 및 할당된 모든 동작과 함께 시스템의 사용자를 나타내는 User 클래스를 사용할 수 있습니다. 그 밖에도 User 개체의 컬렉션과 CRUD 작업을 수행할 관리자 클래스를 사용할 수 있습니다. 어느 정도로 복잡한 수준을 원하는지에 따라 자체 API와 함께 Password 및 Role 개체를 사용할 수도 있습니다. ASP.NET 1.x 코드를 클래스로 다시 작성하는 것이 필수 사항은 아니지만 코드를 ASP.NET 2.0으로 이식하는 작업은 매우 쉬워집니다.


결론

ASP.NET 2.0 멤버 API는 사용자 자격 증명을 처리할 유효성 검사 계층 작성에 사용할 수 있는 확장 가능 모델을 제공합니다. 이렇게 하면 특정 데이터 저장소 및 스키마만 사용할 필요가 없으므로 크게 유리합니다. 또한 보안 관련 사용자 인터페이스를 간단하게 작성할 수 있는 일련의 새로운 서버 컨트롤도 있습니다. 자세한 내용은 "ASP.NET 2.0의 보안 컨트롤" 에서 관련 기사를 참조하십시오.

ASP.NET 2.0의 공급자 모델(전략 패턴의 구현)은 기존의 솔루션을 다시 구성할 필요가 없는 훌륭한 방식을 제공합니다. 멤버 자격에 적용된 공급자 모델을 사용하면 ASP.NET 페이지 및 보안 컨트롤은 미리 정의된 인터페이스를 제공하는 사용자 지정 구성 요소에 연결할 수 있습니다. 어댑터 패턴을 적용하면 보통 ASP.NET 1.x 멤버 자격 시스템의 진입점이 되는 기존의 클래스를 가져올 수 있고 해당 클래스를 조정하여 ASP.NET 2.0 표준 인터페이스를 통해 임의의 내부 정보를 노출할 수 있습니다. 이러한 방법으로 이전의 코드 및 데이터 저장소를 ASP.NET 2.0의 멋진 새로운 세상에서 사용할 수 있습니다. 무엇보다도 여러분은 새로운 기능(예: 보안 컨트롤, 표준 API, 웹 사이트 관리 도구와의 통합 등)을 활용하면서도 대부분의 이전 코드도 여전히 재사용할 수 있는 것입니다.



Dino Esposito 는 Solid Quality Learning의 교사이자 Microsoft ASP.NET 2.0 프로그래밍(2005년 Microsoft Press)의 저자입니다. 이탈리아에 거주하는 Dino는 전세계의 업계 행사에서 자주 연설을 합니다. 전자 메일: cutting@microsoft.com 블로그: weblogs.asp.net/despos (영문)

Andrea SaltarelloManaged Designs (영문)의 기술 이사(Technical Director )이자 수석 소프트웨어 설계자(Chief Software Architect)입니다. 또한 이탈리아 .NET 사용자 그룹에서 ASP.NET 분야의 MVP이자 리더입니다. 블로그: blogs.ugidotnet.org (영문)
페이지 맨 위로페이지 맨 위로QJ: 051104

Microsoft