ASP.NET 멤버십 기능은 사용자를 인증하고 자격 증명을 저장하기 위해 작성 해야하는 코드의 양을 줄입니다. MSDN을 인용하려면 :
"ASP.NET 멤버십은 사용자 자격 증명을 검증하고 저장하는 내장 방법을 제공합니다. 귀하는 ASP.NET 멤버십을 폼 인증 및 / 또는 사용자 인증을위한 ASP.NET 로그인 컨트롤과 함께 사용합니다."
멤버십 제공 업체는 Web.Config 구성 파일에 지정해야합니다. SQLMembershipprovider 제공 업체와 같은 .NET 프레임 워크와 함께 제공되는 자신의 사용자 정의 제공 업체 또는 기본 제공 업체 중 하나를 사용할 수 있습니다.
모든 사용자 관련 데이터는 ASP.NET 멤버십 시스템에서 사용하는 테이블 세트에 저장됩니다. 대부분의 경우 웹 응용 프로그램 당 하나의 테이블 세트를 사용합니다. 그러나 동일한 세트를 재사용하여 여러 웹 응용 프로그램의 사용자 자격 증명을 저장할 수도 있습니다. 이를 통해 효과적으로 이러한 "가상"응용 프로그램 중 하나에 로그인 할 수있는 포털 역할을하는 하나의 웹 응용 프로그램을 만들 수 있습니다.
그러나 이것은 상자에서 불가능합니다. 그러한 동적 응용 프로그램을 지원하기 전에 앞으로의 작업이 있습니다.
시작하자 ...
다음 web.config 항목을 검사하여 시작하겠습니다.
Listing 1- web.config asp.net 멤버십 구성
< membership defaultProvider = " SqlProvider " >
< providers >
< clear />
< add name = " SqlProvider "
type = " System.Web.Security.SqlMembershipProvider "
connectionStringName = " YourConnectionStringName "
applicationName = " MyApplication "
... />
</ providers >
</ membership >이 설정은 SQLMembershipprovider를 사용하여 사용자 자격 증명을 관리하도록 웹 응용 프로그램을 설정합니다. 사용자와 관련된 모든 데이터는 기본 ASP.NET 멤버십 테이블에 저장됩니다.
비고 :이 기사는 ASP.NET 멤버십의 입문서가 아니므로 익숙해야합니다. 데이터베이스를 설정하려면 ASP.NET SQL SERVER 등록 도구 (ASPNET_REGSQL.EXE)를 사용하십시오.
이전에 언급했듯이 여러 웹 응용 프로그램의 사용자 자격 증명을 동일한 테이블 세트에 저장할 수 있습니다. 각 웹 애플리케이션은 사용자 데이터를 응용 프로그램 컨텍스트로 분할하여 사용자 데이터를 분리합니다. 이 응용 프로그램 컨텍스트는 멤버십 제공 업체의 ApplicationName 속성에 의해 정의됩니다. Listing 1에서 볼 수 있듯이 응용 프로그램 이름은 "MyApplication"입니다.
SQLMembershipprovider는이 설정을 사용하여 작동 해야하는 컨텍스트를 결정합니다.이 응용 프로그램 이름에 묶인 모든 사용자 데이터는 ASP.NET 멤버십 라이브러리 및 로그인 컨트롤에서 액세스 할 수 있습니다.
불행히도이 설정은 Web.config에서 정적으로 정의됩니다. 런타임 중에 쉽게 변경할 수 없습니다. 동적 응용 프로그램을 지원하려면 공급자의 ApplicationName 속성의 값을 제어하는 방법이 필요합니다. 솔루션은 자체 ASP.NET 회원 공급자를 만드는 데 있습니다.
sqlmembershipprovider는 web.config 파일에 포함 된 구성 설정에서 ApplicationName 속성의 값을 검색합니다. 우리는이 속성의 getter가 반환하는 값을 변경하고 싶습니다.
사용자 로그인하면 의도를 명확하게해야합니다. 즉, 액세스하려는 가상 응용 프로그램을 지정해야합니다. 이를 위해서는 사용자가 자신의 사용자 이름과 비밀번호뿐만 아니라 액세스하려는 가상 응용 프로그램을 지정해야합니다. 사용자의 관점에서 나는이 가상 응용 프로그램 인 도메인이라고합니다.
예를 들어, ASP.NET 멤버십 테이블이 포함 된 AspNetMembership이라는 SQL Server 데이터베이스를 설정했다고 가정합니다. 이 데이터베이스에는 aspnet_applications 테이블에 정의 된 다음 가상 응용 프로그램이 포함되어 있습니다.
각 가상 응용 프로그램에는 사용자 이름 "CGEERS"가있는 사용자가 포함됩니다. 이제 Northwind 응용 프로그램에 로그인하려면 사용자 이름을 "Northwind Cgeers"로 입력해야합니다. AdventureWorks 응용 프로그램의 경우 이것은 "AdventureWorks cgeers"입니다.
사용자 이름 앞의 부분은 응용 프로그램 이름이거나 사용자가 우려하는 한 이것이 액세스 할 가상 애플리케이션을 지정하기 위해 입력 해야하는 도메인입니다. 도메인과 사용자 이름은 백 슬래시로 분리됩니다.
사용자가 ASP.NET 로그인 컨트롤을 사용하여 로그인하면 입력 한 도메인을 추출하고 사용자 정의 멤버십 제공 업체가 액세스 할 수있는 위치에 저장해야합니다. 그러나 ASP.NET은 다중 스레드 환경에서 작동한다는 점을 고려해야합니다. ASP.NET에서받은 각 요청은 별도의 스레드로 처리됩니다. 우리는 도메인을 어느 위치에도 저장할 수 없으며, 다른 Whise의 다른 수신 요청은 그것을 덮어 쓸 수 있습니다. 단일 요청에 연결되어 있어야합니다.
개별 요청과 관련된 상황 정보를 저장하기에 이상적인 장소는 현재 HTTP 컨텍스트입니다. 이러한 맥락 정보는 HTTPContext 클래스에 의해 캡슐화됩니다.
Visual Studio를 시작하고 "AspnetDynamicApplications"라는 새로운 빈 솔루션을 만듭니다. 그런 다음 "Cgeers.Web.Security"라는 솔루션에 새 클래스 라이브러리 프로젝트를 추가하십시오. 시스템에 대한 참조를 추가하십시오. 구성 및 System.Web Assemblies. 당사의 사용자 정의 제공 업체는 기본 SQLMembershipprovider에서 내려 가므로 이러한 참조가 필요합니다.
그림 1- 비주얼 스튜디오 솔루션

자동으로 생성 된 class1.cs 파일의 이름을 DynamicApplicationsSqlMembershipProvider.cs로 바꾸고 Listing 2에 표시된 코드를 추가하십시오.
Listing 2- DynamicAbplicationsSQLMembershipprovider
public class DynamicApplicationsSqlMembershipProvider : SqlMembershipProvider
{
#region Fields
private const string ApplicationNameSetting = "ApplicationName" ;
#endregion
public override string ApplicationName
{
get
{
HttpContext context = HttpContext . Current ;
if ( context == null )
{
throw new InvalidOperationException ( "Http context cannot be null." ) ;
}
string applicationName = String . Empty ;
if ( context . Items . Contains ( ApplicationNameSetting ) )
{
if ( ! String . IsNullOrEmpty ( ( string ) context . Items [ ApplicationNameSetting ] ) )
{
applicationName = ( string ) context . Items [ ApplicationNameSetting ] ;
}
}
return applicationName ;
}
set
{
base . ApplicationName = value ;
}
}
}보시다시피 우리의 사용자 정의 멤버십 제공 업체는 기본 sqlmembershipprovider에서 내려와 ApplicationName 속성을 재정의합니다. 우리는 세터와 걱정하지 않고 게터와 만 걱정하지 않습니다. 공급자가 ApplicationName 속성을 읽으면 HTTPContext 클래스의 정적 전류 속성을 호출하여 현재 HTTP 컨텍스트를 처리합니다. 얻은 HTTPContext 객체에는 항목이라는 키/값 수집 속성이 있습니다. 이 모음은 "ApplicationName"의 키로 식별 된 항목에 응용 프로그램 이름을 저장합니다. 이 키의 이름은 설계 시간에 결정해야 할 것입니다.
이제 사용자 정의 멤버십 제공 업체가 응용 프로그램 이름을 결정해야 할 때마다 ApplicationName 속성을 호출하여 현재 HTTP 컨텍스트에서 값을 검색합니다. 이는 각 요청이 자체 HTTP 컨텍스트에 연결되어 있으므로 ASP.NET의 멀티 스레드 환경에서 작동합니다.
이제 Currect HTTP 컨텍스트에서 ApplicationName 속성의 값을 검색하는 사용자 정의 멤버십 제공 업체이므로 HTTP 컨텍스트에 응용 프로그램 이름을 실제로 저장하는 방법을 찾아야합니다.
사용자가 처음으로 액세스하려는 가상 애플리케이션 또는 도메인을 지정하는 것은 로그인 할 때입니다. 앞에서 언급했듯이 사용자는 <domain><username> 형식으로 사용자 이름을 입력해야합니다. ASP.NET 로그인 컨트롤에서 내려 오는 자체 로그인 컨트롤을 작성해야합니다. 사용자 인증시 입력 한 도메인을 추출하여 현재 HTTP 컨텍스트에 저장해야합니다.
"cgeers.web.ui.webcontrols"라는 솔루션에 클래스 라이브러리 템플릿을 사용하여 새 프로젝트를 추가하십시오. 프로젝트에 다음 참조를 추가하십시오.
다음으로 자동 생성 된 class1.cs 파일을 삭제하고 DynamicApplicationSlogin이라는 새 클래스를 추가하십시오. 이 클래스의 코드는 매우 길기 때문에 여러 목록으로 나누기로 선택했습니다. 각 목록 후에 코드에 대한 간단한 설명이 추가됩니다.
Listing 3- DynamicApplicationsLogin Control 개인 특성
public class DynamicApplicationsLogin : Login
{
#region Fields
private string _fullUserName ;
#endregion
#region Properties
private string ApplicationName
{
get
{
string [ ] data = base . UserName . Split ( @"" . ToCharArray ( ) , 2 ) ;
string applicationName = ( data . Length == 2 ) ? data [ 0 ] : String . Empty ;
return applicationName ;
}
}
private string BaseUserName
{
get
{
string [ ] data = base . UserName . Split ( @"" . ToCharArray ( ) , 2 ) ;
string userName = ( data . Length == 2 ) ? data [ 1 ] : base . UserName ;
return userName ;
}
}
#endregion
// ...
}보시다시피 DynamicApplications 컨트롤은 표준 ASP.NET 로그인 컨트롤과 _fullusername이라는 필드와 두 개의 개인 속성 ApplicationName 및 BaseUserName이 추가됩니다.
사용자는 도메인과 사용자 이름을 동일한 텍스트 상자 컨트롤에 입력하므로 이러한 부분을 분할해야합니다. 당신이 추측 할 수 있듯이 ApplicationName 속성은 도메인을 추출하고 BaseuserName은 사용자 이름을 반환합니다. 예를 들어, 사용자가 Northwind Cgeers에 들어가면 ApplicationName 속성은 "Northwind"를 반환하고 BaseUserName 속성은 "CGEERS"를 반환합니다.
Listing 4- DynamicApplicationslogin Control Oneuthenticate 방법
protected override void OnAuthenticate ( AuthenticateEventArgs e )
{
HttpContext context = HttpContext . Current ;
if ( context == null )
{
throw new InvalidOperationException ( "Http context cannot be null." ) ;
}
MembershipProvider provider = Membership . Provider ;
if ( provider == null )
{
throw new InvalidOperationException ( "MembershipProvider cannot be null." ) ;
}
provider = provider as DynamicApplicationsSqlMembershipProvider ;
if ( provider == null )
{
throw new InvalidOperationException (
"The specified MembershipProvider must be of type DynamicApplicationsSqlMembershipProvider." ) ;
}
// Store the application name in the current Http context's items collections
context . Items [ "ApplicationName" ] = ApplicationName ;
// Validate the user
_fullUserName = UserName ;
UserName = BaseUserName ;
base . OnAuthenticate ( e ) ;
}다음으로 사용자가 올바른 응용 프로그램 컨텍스트 (Virtual Application) 내부에서 검증되어 있는지 확인하려면 로그인 컨트롤의 Onuthenticate 메소드를 무시해야합니다.
먼저이 메소드는 현재 HTTP 컨텍스트에 대한 참조를 검색 한 다음로드 된 멤버십 제공 업체가 실제로 사용자 정의 DynamicApplicationsSQLMembershipProvider인지 확인합니다. 그런 다음 입력 된 도메인 또는 응용 프로그램 이름은 현재 HTTP Context의 항목 컬렉션에 저장되어 멤버십 제공 업체가 ApplicationName 속성의 올바른 값을 검색 할 수 있습니다.
마지막으로 사용자 이름 속성의 값은 BaseUserName 속성을 할당하여 사용자 이름 만 포함하도록 설정됩니다. 개인 _fullusername 필드는 사용자가 입력 한 값 (도메인 username)을 임시로 저장합니다. 이 필드가 나중에 어떻게 사용되는지 볼 수 있습니다.
애플리케이션 이름이 HTTP 컨텍스트에 저장되고 사용자 이름 속성에만 기본 구현이 호출되는 사용자 이름 만 포함되면 사용자 이름이 올바른 응용 프로그램 컨텍스트 내부에서 검증됩니다.
Listing 5 -dynamicapplicationslogin 컨트롤 OnloginError 방법
protected override void OnLoginError ( EventArgs e )
{
UserName = _fullUserName ;
base . OnLoginError ( e ) ;
}OnloginError 메소드를 무시하고 기본 구현을 호출하기 전에 _fullusername 필드를 사용자 이름 속성에 할당하십시오. 사용자를 인증 할 때 (onauthenticate 메서드) 사용자 이름 속성에는 도메인이 아닌 사용자 이름 만 포함해야하지만 인증이 실패하면 사용자 이름을 나타내는 텍스트 상자 컨트롤에 입력 한 텍스트가 사용자가 처음 입력 한 값으로 재설정되어 있는지 확인해야합니다. 그가 입력 한 도메인이 사라지면 사용자에게 혼란 스러울 수 있습니다.
Listing 6- DynamicApplicationslogin Control Onloggedin 방법
protected override void OnLoggedIn ( EventArgs e )
{
UserName = _fullUserName ;
HttpContext context = HttpContext . Current ;
if ( context == null )
{
throw new InvalidOperationException ( "Http context cannot be null." ) ;
}
string userName = BaseUserName ;
MembershipUser user = Membership . GetUser ( userName ) ;
if ( user != null )
{
string userData = String . Format ( "AN={0};" , ApplicationName ) ;
HttpCookie cookie = FormsAuthenticationHelper . StoreUserDataInAuthenticationCookie (
userName , userData , RememberMeSet
) ;
// Manually add the cookie to the Cookies collection
context . Response . Cookies . Add ( cookie ) ;
}
}DynamicApplicationsLogin Control을 완료하려면 Onloggedin 방법을 무시해야합니다. 응용 프로그램 이름은 FormsAuthenticationTicket의 userData 속성에 저장됩니다. 이 인증 티켓은 Forms 인증에 의해 인증 된 사용자를 식별하기 위해 사용됩니다. 여기에서 쿠키에 저장하고 현재 HTTP 컨텍스트의 응답에 추가합니다. 나중에 이것이 왜 필요한지 알 수 있습니다.
Listing 6을 살펴보면 양식 인증 티켓이 포함 된 쿠키가 FormsAuthenticationHelper라는 도우미 클래스에 의해 생성된다는 것을 알 수 있습니다. 이것은 하나의 방법, 즉 StoreUserDatainauthenticationCookie 만 포함하는 정적 헬퍼 클래스입니다.
cgeers.web.security project에 formsauthenticationHelper라는 새 클래스를 추가하고 목록 7에 표시된 코드를 추가하십시오.
Listing 7- FormsauthenticationHelper
public static class FormsAuthenticationHelper
{
public static HttpCookie StoreUserDataInAuthenticationCookie (
string userName , string userData , bool persistent )
{
if ( String . IsNullOrEmpty ( userName ) )
{
throw new InvalidOperationException ( "UserName cannot be null or empty." ) ;
}
if ( String . IsNullOrEmpty ( userData ) )
{
throw new InvalidOperationException ( "User data cannot be null or empty." ) ;
}
// Create the cookie that contains the forms authentication ticket
HttpCookie cookie = FormsAuthentication . GetAuthCookie ( userName , persistent ) ;
// Get the FormsAuthenticationTicket out of the encrypted cookie
FormsAuthenticationTicket ticket = FormsAuthentication . Decrypt ( cookie . Value ) ;
// Create a new FormsAuthenticationTicket that includes our custom user data
FormsAuthenticationTicket newTicket = new FormsAuthenticationTicket ( ticket . Version ,
ticket . Name ,
ticket . IssueDate ,
ticket . Expiration ,
persistent ,
userData ) ;
// Update the cookie's value to use the encrypted version of our new ticket
cookie . Value = FormsAuthentication . Encrypt ( newTicket ) ;
// Return the cookie
return cookie ;
}
}StoreUserDatainauthenticationCookie (...) 메소드는 양식 인증 티켓이 포함 된 지정된 사용자 (사용자 이름 매개 변수)의 쿠키를 검색합니다. 다음으로 FormsAuthenticationTicket 객체에 액세스하기 위해 쿠키가 해독됩니다. 그런 다음 이전 티켓에 따라 새로운 FormsAuthenticationTicket이 작성되며 userData 매개 변수에 포함 된 값은이 티켓 내에 저장됩니다. 마지막 단계로, 새로운 FormsAuthenticationTicket 객체는 암호화 된 쿠키 내에 저장됩니다.
비고 : DynamicApplicationsLogin Control Stores는이 쿠키를 사용자에게 다시 보내므로 클라이언트는 쿠키를 지원해야합니다!
우리가 지금까지 가지고있는 것을 되 찾으십시오.
따라서 요청에 따라 작동 할 애플리케이션 컨텍스트를 결정할 수있는 사용자 정의 멤버십 제공 업체가 있으며 사용자가 도메인 (= 응용 프로그램 이름)으로 사용자 이름을 선행하도록 요구 하여이 컨텍스트를 식별하는 사용자 정의 로그인 컨트롤이 있습니다.
웹 애플리케이션이 로그인 페이지로 구성된 경우에도 잘 작동합니다. 사용자 정의 멤버십 제공 업체는 현재 HTTP 컨텍스트에 저장된 응용 프로그램 이름을 읽음으로써 응용 프로그램 컨텍스트를 결정합니다. 각 요청마다 새로운 HTTP 컨텍스트가 생성됩니다. 응용 프로그램 이름에 로그인 할 때 HTTP 컨텍스트 내에 명시 적으로 저장됩니다. 그러나 후속 요청의 경우 그렇지 않습니다. 어떻게 든 사용자가 로그인 한 후 각 요청과 함께 HTTP 컨텍스트가 응용 프로그램 이름으로 올바르게 초기화되어 있는지 확인해야합니다.
앞에서 언급했듯이 DynamicApplicationLogin Control은 성공적으로 로그인 한 후 암호화 된 쿠키를 사용자에게 보냅니다.이 쿠키에는 응용 프로그램 이름이 포함되어 있으며 각 후속 요청과 함께 전송됩니다. Voila, 이제 우리가 필요한 것은이 쿠키의 내용을 읽고 HTTP 컨텍스트에 검색된 응용 프로그램 이름을 저장하기 위해 ASP.NET 요청 파이프 라인에 일부 논리를 삽입하는 방법 만 있으면됩니다.
HTTP 모듈은이 상황에 적합합니다. HTTP 모듈은 모든 요청에서 호출되며 요청이 처리되기 전후에 실행됩니다.
cgeers.web.security project에 DynamicApplicationSmodule이라는 새 클래스를 추가하십시오. 이 클래스는 ihttpmodule 인터페이스를 구현해야합니다. 이 HTTP 모듈의 코드는 Listing 8에 표시됩니다.
Listing 8- DynamicApplicationSmodule
public class DynamicApplicationsModule : IHttpModule
{
#region Fields
private const string ApplicationNameSetting = "ApplicationName" ;
#endregion
#region IHttpModule Members
public void Dispose ( )
{ }
public void Init ( HttpApplication context )
{
context . AuthenticateRequest += DetermineApplicationName ;
}
#endregion
private static void DetermineApplicationName ( object sender , EventArgs e )
{
// Access the current Http application.
HttpApplication application = sender as HttpApplication ;
if ( application == null )
{
throw new InvalidOperationException ( "Http application cannot be null." ) ;
}
// Get the HttpContext for the current request.
HttpContext context = application . Context ;
if ( context == null )
{
throw new InvalidOperationException ( "Http context cannot be null." ) ;
}
// Read the application name stored in the FormsAuthenticationTicket
string applicationName = String . Empty ;
if ( context . Request . IsAuthenticated )
{
FormsIdentity identity = context . User . Identity as FormsIdentity ;
if ( identity != null )
{
FormsAuthenticationTicket ticket = identity . Ticket ;
if ( ticket != null )
{
applicationName = ticket . GetApplicationName ( ) ;
}
}
}
// Store the application name in the Items collection of the per-request http context.
// Storing it in the session state is not an option as the session is not available at this
// time. It is only available when the Http application triggers the AcquireRequestState event.
context . Items [ ApplicationNameSetting ] = applicationName ;
}
}init (...) 메소드는 HTTP 모듈을 초기화하고 요청을 처리하도록 준비합니다. 여기서 HTTPapplication의 AuthenticAteRequest 이벤트는 DecineApplicationName 이벤트 핸들러에 연결됩니다.
DecineApplicationName (...) 이벤트 핸들러는 인증 된 요청을 처리하는지 확인하고 클라이언트가 보낸 Formsauthentication 티켓을 검색하는지 확인합니다.
이 티켓은 작동 할 응용 프로그램 컨텍스트를 식별합니다. 응용 프로그램 이름은 FormsAuthenticationTicket의 getApplicationName () 메소드를 사용하여 티켓에서 추출됩니다. 이것은 확장 방법입니다. 다음 섹션에서 다루겠습니다.
마지막으로 티켓에서 응용 프로그램 이름을 추출한 후 HTTP 컨텍스트 내에 저장되어 사용자 정의 멤버십 제공 업체가 읽을 수 있습니다.
cgeers.web.security project에 formsauthenticationticketextensions라는 새 클래스를 추가하고 Listing 9에 표시된 코드를 추가하십시오.
Listing 9- FormsauthenticationTickEtextensions
internal static class FormsAuthenticationTicketExtensions
{
public static string GetApplicationName ( this FormsAuthenticationTicket ticket )
{
// Check if the application name (AN=) is stored in the ticket's userdata.
string applicationName = String . Empty ;
List < string > settings = new List < string > ( ticket . UserData . Split ( ';' ) ) ;
foreach ( string s in settings )
{
string setting = s . Trim ( ) ;
if ( setting . StartsWith ( "AN=" ) )
{
int startIndex = setting . IndexOf ( "AN=" ) + 3 ;
applicationName = setting . Substring ( startIndex ) ;
break ;
}
}
return applicationName ;
}
}Listing 6에서 볼 수 있듯이 DynamicApplicationLogin Control은 FormsAuthenticationTicket의 userData 속성에서 애플리케이션 이름을 Prefix "an ="로 선행하여 저장합니다. 따라서이 확장 방법은 FormsAuthenticationTicket에서 응용 프로그램 이름을 검색 할 때이를 고려해야합니다.
비고 : 응용 프로그램 이름이 티켓 내에 저장되는 방식에 자유롭게 개선하십시오. 그러나 DynamicApplicationsLogin Control 및이 확장 방법에 대해 동일한 시스템을 구현해야합니다.
DynamicApplicationsLogin Control과 유사하게 ASP.NET PasswordRecovery 및 ChangePassword 컨트롤에서 내려 오는 컨트롤을 만들었습니다. 사용자가 자신의 비밀번호를 검색하거나 변경할 수 있으려면 이러한 컨트롤을 사용해야합니다. 그들은 올바른 응용 프로그램 컨텍스트 내에서 모든 것이 실행되도록합니다.
구현은 DynamicApplicationsLogin Control의 구현과 매우 유사하므로 이러한 컨트롤의 코드를 여기에 나열하지 않습니다. 이러한 컨트롤의 소스 코드를 확인하려면이 기사와 함께 제공되는 소스 코드를 다운로드하십시오. Cgeers.web.ui.webControls 프로젝트에서 이러한 컨트롤을 찾을 수 있습니다.
이 기사와 함께 제공되는 소스 코드에는 DynamicApplicationssqlmembershipprovider, 새로운 로그인 컨트롤, 사용자 정의 HTTP 모듈 등을 보여주는 데모 웹 응용 프로그램 프로젝트도 포함되어 있습니다.
그림 2- 비주얼 스튜디오 솔루션

이 데모 애플리케이션을 실행하려면 다음을 수행하십시오.
이 단계를 수행 한 후에는 데모 웹 응용 프로그램을 실행할 준비가되어 있어야합니다. 각 응용 프로그램에 대해 두 개의 응용 프로그램과 사용자가 포함 된 데이터베이스를 만들었습니다.
웹 응용 프로그램을 시작하면 응용 프로그램 이름 (도메인)을 사양 한 다음 백 슬래시 및 사용자 이름을 지정하여 각 응용 프로그램에 로그인 할 수 있습니다. 물론 사용자의 비밀번호도 필요합니다.
우리가 만든 로그인 컨트롤은 나머지를 관리하고 올바른 응용 프로그램 컨텍스트 내에서 작동하는지 확인하십시오. ASP.NET 멤버십 라이브러리와의 후속 통화는 사용자 정의 멤버십 제공 업체가 올바른 응용 프로그램 이름을 반환하도록 트리거하여 이러한 통화가 올바른 응용 프로그램 컨텍스트 내에서 작동하도록합니다.
비고 : 데모 웹 애플리케이션의 web.config 파일에는 응용 프로그램을 올바르게 설정하기 위해해야 할 모든 것을 지정하는 주석이 포함되어 있습니다. 확인하십시오.
이 기사에서는 ASP.NET 멤버십 시스템을 사용하여 사용자가 많은 가상 응용 프로그램 중 하나에 로그인 할 수있는 포털 응용 프로그램을 만들 수있는 방법을 보여주었습니다.
이를 실현하는 첫 번째 열쇠는 개별 요청에 연결된 스토리지 위치에서 ApplicationName 속성의 값을 검색하여 올바른 응용 프로그램 컨텍스트 내에서 작동하는 사용자 정의 멤버십 제공 업체를 작성하는 것입니다.
표준 ASP.NET 로그인 컨트롤에서 내려가는 사용자 정의 로그인 컨트롤을 작성하면 사용자가 액세스하려는 응용 프로그램을 결정할 수 있습니다.
암호화 된 쿠키 로이 정보를 캡슐화함으로써 사용자가 각 요청에 대해 액세스하려는 응용 프로그램을 자동으로 식별 할 수 있습니다.