SQL Server에서 멤버 자격 스키마 만들기(VB)

작성자 : Scott Mitchell

참고

이 문서가 작성된 이후 ASP.NET 멤버 자격 공급자는 ASP.NET ID로 대체되었습니다. 이 문서를 작성할 때 추천하는 멤버 자격 공급자가 아닌 ASP.NET ID 플랫폼을 사용하도록 앱을 업데이트하는 것이 좋습니다. ASP.NET ID는 를 포함하여 ASP.NET 멤버 자격 시스템에 비해 여러 가지 이점이 있습니다.

  • 성능 향상
  • 향상된 확장성 및 테스트 용이성
  • OAuth, OpenID Connect 및 2단계 인증 지원
  • 클레임 기반 ID 지원
  • ASP.Net Core와의 상호 운용성 향상

코드 다운로드 또는 PDF 다운로드

이 자습서에서는 SqlMembershipProvider를 사용하기 위해 데이터베이스에 필요한 스키마를 추가하는 기술을 검토하는 것으로 시작합니다. 그런 다음 스키마의 주요 테이블을 검토하고 해당 목적과 중요도에 대해 설명합니다. 이 자습서는 멤버 자격 프레임워크에서 사용해야 하는 공급자를 ASP.NET 애플리케이션에 알리는 방법을 살펴보는 것으로 끝납니다.

소개

이전 두 자습서에서는 양식 인증을 사용하여 웹 사이트 방문자를 식별하는 방법을 검토했습니다. 양식 인증 프레임워크를 사용하면 개발자가 사용자를 웹 사이트에 쉽게 로그하고 인증 티켓을 사용하여 페이지 방문에서 사용자를 기억할 수 있습니다. 클래스에는 FormsAuthentication 티켓을 생성하고 방문자의 쿠키에 추가하는 메서드가 포함됩니다. 는 FormsAuthenticationModule 들어오는 모든 요청을 검사하고 유효한 인증 티켓이 있는 요청의 경우 및 개체를 GenericPrincipalFormsIdentity 만들고 현재 요청과 연결합니다. 양식 인증은 로그인할 때 방문자에게 인증 티켓을 부여하고 후속 요청에 따라 해당 티켓을 구문 분석하여 사용자의 ID를 확인하는 메커니즘일 뿐입니다. 웹 애플리케이션이 사용자 계정을 지원하려면 여전히 사용자 저장소를 구현하고 자격 증명의 유효성을 검사하고, 새 사용자를 등록하고, 수많은 다른 사용자 계정 관련 작업을 수행하는 기능을 추가해야 합니다.

ASP.NET 2.0 이전에는 개발자가 이러한 모든 사용자 계정 관련 작업을 구현하기 위한 후크에 있었습니다. 다행히 ASP.NET 팀은 이러한 단점을 인식하고 ASP.NET 2.0의 멤버 자격 프레임워크를 도입했습니다. 멤버 자격 프레임워크는 핵심 사용자 계정 관련 작업을 수행하기 위한 프로그래밍 인터페이스를 제공하는 .NET Framework 클래스 집합입니다. 이 프레임워크는 개발자가 사용자 지정된 구현을 표준화된 API에 연결할 수 있도록 하는 공급자 모델 위에 빌드됩니다.

보안 기본 사항 및 ASP.NET 지원 자습서에서 설명한 대로 .NET Framework 및 의 두 가지 기본 제공 멤버 자격 공급자 ActiveDirectoryMembershipProviderSqlMembershipProvider함께 제공됩니다. 이름에서 알 수 있듯이 는 SqlMembershipProvider Microsoft SQL Server 데이터베이스를 사용자 저장소로 사용합니다. 애플리케이션에서 이 공급자를 사용하려면 저장소로 사용할 데이터베이스를 공급자에게 알려야 합니다. 상상할 수 있듯이 는 SqlMembershipProvider 사용자 저장소 데이터베이스에 특정 데이터베이스 테이블, 뷰 및 저장 프로시저가 있어야 합니다. 이 예상 스키마를 선택한 데이터베이스에 추가해야 합니다.

이 자습서에서는 를 사용하기 위해 데이터베이스에 필요한 스키마를 추가하는 기술을 검토하는 것으로 시작합니다 SqlMembershipProvider. 그런 다음 스키마의 주요 테이블을 검토하고 해당 목적과 중요도에 대해 설명합니다. 이 자습서는 멤버 자격 프레임워크에서 사용해야 하는 공급자를 ASP.NET 애플리케이션에 알리는 방법을 살펴보는 것으로 끝납니다.

그럼 시작하겠습니다.

1단계: 사용자 저장소를 배치할 위치 결정

ASP.NET 애플리케이션의 데이터는 일반적으로 데이터베이스의 여러 테이블에 저장됩니다. 데이터베이스 스키마를 SqlMembershipProvider 구현할 때 멤버 자격 스키마를 애플리케이션 데이터와 동일한 데이터베이스에 배치할지 또는 대체 데이터베이스에 배치할지 결정해야 합니다.

다음과 같은 이유로 애플리케이션 데이터와 동일한 데이터베이스에 멤버 자격 스키마를 찾는 것이 좋습니다.

  • 한 데이터베이스에 데이터가 캡슐화된 애플리케이션의 유지 관리 효율성은 두 개의 개별 데이터베이스가 있는 애플리케이션보다 쉽게 이해하고 유지 관리하고 배포할 수 있습니다.
  • 애플리케이션 테이블과 동일한 데이터베이스에 멤버 자격 관련 테이블을 배치하여 관계형 무결성은 멤버 자격 관련 테이블과 관련 애플리케이션 테이블의 기본 키 간에 외래 키 제약 조건을 설정할 수 있습니다.

사용자 저장소와 애플리케이션 데이터를 별도의 데이터베이스로 분리하는 것은 각각 별도의 데이터베이스를 사용하는 여러 애플리케이션이 있지만 공통 사용자 저장소를 공유해야 하는 경우에만 의미가 있습니다.

데이터베이스 만들기

두 번째 자습서부터 빌드한 애플리케이션에는 데이터베이스가 아직 필요하지 않습니다. 그러나 이제 사용자 저장소에 대해 필요합니다. 하나를 만든 다음 공급자에 필요한 스키마를 SqlMembershipProvider 추가해 보겠습니다(2단계 참조).

참고

이 자습서 시리즈 전체에서 Microsoft SQL Server 2005 Express Edition 데이터베이스를 사용하여 애플리케이션 테이블과 스키마를 저장합니다SqlMembershipProvider. 이 결정은 두 가지 이유로 이루어졌다: 첫째, 그 비용으로 인해 - 무료 - Express Edition은 SQL Server 2005의 가장 읽기 쉬운 버전입니다; 두 번째, SQL Server 2005 Express Edition 데이터베이스는 웹 애플리케이션의 App_Data 에 직접 배치 할 수 있습니다 폴더를 사용하면 데이터베이스와 웹 애플리케이션을 하나의 ZIP 파일로 패키지하고 특별한 설정 지침이나 구성 옵션 없이 다시 배포할 수 있습니다. Express 버전이 아닌 버전의 SQL Server 사용하려는 경우 무료입니다. 단계는 거의 동일합니다. 스키마는 SqlMembershipProvider 모든 버전의 Microsoft SQL Server 2000 이상에서 작동합니다.

솔루션 탐색기 폴더를 App_Data 마우스 오른쪽 단추로 클릭하고 새 항목 추가를 선택합니다. (프로젝트에 폴더가 App_Data 표시되지 않으면 솔루션 탐색기 프로젝트를 마우스 오른쪽 단추로 클릭하고 ASP.NET 폴더 추가를 선택하고 를 선택합니다App_Data. 새 항목 추가 대화 상자에서 라는 SecurityTutorials.mdf새 SQL Database 추가하도록 선택합니다. 이 자습서에서는 이 데이터베이스에 SqlMembershipProvider 스키마를 추가합니다. 후속 자습서에서는 애플리케이션 데이터를 캡처하기 위한 추가 테이블을 만듭니다.

새 SQL Database 명명된 SecurityTutorials.mdf 데이터베이스를 App_Data 폴더에 추가

그림 1: 폴더에 새 SQL Database 명명된 SecurityTutorials.mdf 데이터베이스 App_Data 추가(전체 크기 이미지를 보려면 클릭)

폴더에 데이터베이스를 App_Data 추가하면 데이터베이스 Explorer 보기에 자동으로 포함됩니다. (Visual Studio의 비 Express Edition 버전에서는 Database Explorer Server Explorer라고 합니다.) 데이터베이스 Explorer 이동하여 방금 추가 SecurityTutorials 한 데이터베이스를 확장합니다. 화면에 데이터베이스 Explorer 표시되지 않으면 보기 메뉴로 이동하여 데이터베이스 Explorer 선택하거나 Ctrl+Alt+S를 누릅니다. 그림 2에서 SecurityTutorials 볼 수 있듯이 데이터베이스는 비어 있습니다. 여기에는 테이블, 뷰, 저장 프로시저가 포함되지 않습니다.

SecurityTutorials 데이터베이스가 현재 비어 있음

그림 2: SecurityTutorials 데이터베이스가 현재 비어 있음(전체 크기 이미지를 보려면 클릭)

2단계: 데이터베이스에SqlMembershipProvider스키마 추가

SqlMembershipProvider 을 사용하려면 특정 테이블, 뷰 및 저장 프로시저 집합을 사용자 저장소 데이터베이스에 설치해야 합니다. 이러한 필수 데이터베이스 개체는 도구를 사용하여 aspnet_regsql.exe추가할 수 있습니다. 이 파일은 폴더에 %WINDIR%\Microsoft.Net\Framework\v2.0.50727\ 있습니다.

참고

이 도구는 aspnet_regsql.exe 명령줄 기능과 그래픽 사용자 인터페이스를 모두 제공합니다. 그래픽 인터페이스는 사용자에게 더 친숙하며 이 자습서에서 살펴볼 내용입니다. 명령줄 인터페이스는 빌드 스크립트 또는 자동화된 테스트 시나리오와 같이 스키마 추가 SqlMembershipProvider 를 자동화해야 하는 경우에 유용합니다.

도구 aspnet_regsql.exe 는 지정된 SQL Server 데이터베이스에 ASP.NET 애플리케이션 서비스를 추가하거나 제거하는 데 사용됩니다. ASP.NET 애플리케이션 서비스는 및 에 대한 SqlMembershipProvider 스키마와 SqlRoleProvider다른 ASP.NET 2.0 프레임워크용 SQL 기반 공급자에 대한 스키마를 포함합니다. 도구에 다음 두 비트의 정보를 aspnet_regsql.exe 제공해야 합니다.

  • 애플리케이션 서비스를 추가하거나 제거할지 여부 및
  • 애플리케이션 서비스 스키마를 추가하거나 제거할 데이터베이스

데이터베이스를 사용 aspnet_regsql.exe 하라는 메시지가 표시되면 도구는 데이터베이스가 있는 서버의 이름, 데이터베이스에 연결하기 위한 보안 자격 증명 및 데이터베이스 이름을 제공하도록 요청합니다. 비 Express 버전의 SQL Server 사용하는 경우 ASP.NET 웹 페이지를 통해 데이터베이스로 작업할 때 연결 문자열 통해 제공해야 하는 것과 동일한 정보이므로 이 정보를 이미 알고 있어야 합니다. 그러나 폴더에서 SQL Server 2005 Express Edition 데이터베이스를 사용할 때 서버 및 데이터베이스 App_Data 이름을 확인하는 것이 좀 더 복잡합니다.

다음 섹션에서는 폴더에 있는 SQL Server 2005 Express Edition 데이터베이스의 서버 및 데이터베이스 App_Data 이름을 지정하는 간단한 방법을 살펴봅니다. SQL Server 2005 Express Edition 사용하지 않는 경우 Application Services 설치 섹션으로 건너뛸 수 있습니다.

폴더에서 SQL Server 2005 Express Edition 데이터베이스의 서버 및 데이터베이스App_Data이름 확인

도구를 사용 aspnet_regsql.exe 하려면 서버 및 데이터베이스 이름을 알아야 합니다. 서버 이름은 입니다 localhost\InstanceName. 대부분의 경우 InstanceName은 입니다SQLExpress. 그러나 SQL Server 2005 Express Edition 수동으로 설치한 경우(즉, Visual Studio를 설치하는 동안 자동으로 설치하지 않음) 다른 instance 이름을 선택했을 수 있습니다.

데이터베이스 이름은 확인하기가 좀 더 까다롭습니다. 폴더의 App_Data 데이터베이스에는 일반적으로 데이터베이스 파일 경로와 함께 전역적으로 고유한 식별자가 포함된 데이터베이스 이름이 있습니다. 를 통해 aspnet_regsql.exe애플리케이션 서비스 스키마를 추가하려면 이 데이터베이스 이름을 결정해야 합니다.

데이터베이스 이름을 확인하는 가장 쉬운 방법은 SQL Server Management Studio 통해 검사하는 것입니다. SQL Server Management Studio SQL Server 2005 데이터베이스를 관리하기 위한 그래픽 인터페이스를 제공하지만 SQL Server 2005의 Express Edition과 함께 제공되지는 않습니다. 좋은 소식은 SQL Server Management Studio 무료 Express Edition을 다운로드할 수 있다는 것입니다.

참고

데스크톱에 Express 버전이 아닌 버전의 SQL Server 2005도 설치되어 있는 경우 전체 버전의 Management Studio가 설치될 가능성이 높습니다. Express Edition에 대해 아래에 설명된 것과 동일한 단계에 따라 전체 버전을 사용하여 데이터베이스 이름을 확인할 수 있습니다.

먼저 Visual Studio를 닫아 데이터베이스 파일에서 Visual Studio에서 적용한 잠금이 닫혀 있는지 확인합니다. 다음으로, SQL Server Management Studio 시작하고 SQL Server 2005 Express Edition 데이터베이스에 연결 localhost\InstanceName 합니다. 앞에서 설명한 것처럼 instance 이름이 일 수 있습니다SQLExpress. 인증 옵션에서 Windows 인증을 선택합니다.

SQL Server 2005 Express Edition 인스턴스에 연결

그림 3: SQL Server 2005 Express Edition 인스턴스에 연결(전체 크기 이미지를 보려면 클릭)

SQL Server 2005 Express Edition instance 연결한 후 Management Studio는 데이터베이스, 보안 설정, 서버 개체 등에 대한 폴더를 표시합니다. 데이터베이스 탭을 확장하면 데이터베이스가 데이터베이스 instance 등록되지 않은 것을 볼 SecurityTutorials.mdf 수 있습니다. 먼저 데이터베이스를 연결해야 합니다.

데이터베이스 폴더를 마우스 오른쪽 단추로 클릭하고 상황에 맞는 메뉴에서 연결을 선택합니다. 그러면 데이터베이스 연결 대화 상자가 표시됩니다. 여기에서 추가 단추를 클릭하고 데이터베이스로 이동한 SecurityTutorials.mdf 다음 확인을 클릭합니다. 그림 4는 데이터베이스를 선택한 후 SecurityTutorials.mdf 데이터베이스 연결 대화 상자를 보여 줍니다. 그림 5는 데이터베이스가 성공적으로 연결된 후 Management Studio의 개체 탐색기 보여줍니다.

SecurityTutorials.mdf 데이터베이스 연결

그림 4: 데이터베이스 연결 SecurityTutorials.mdf (전체 크기 이미지를 보려면 클릭)

데이터베이스 폴더에 SecurityTutorials.mdf 데이터베이스가 나타납니다.

그림 5: SecurityTutorials.mdf 데이터베이스 폴더에 데이터베이스가 나타납니다(전체 크기 이미지를 보려면 클릭).

그림 5에서 알 수 있듯이 데이터베이스의 SecurityTutorials.mdf 이름은 다소 비독성입니다. 더 기억에 남는(그리고 더 쉽게 입력할 수 있는) 이름으로 변경해 보겠습니다. 데이터베이스를 마우스 오른쪽 단추로 클릭하고 상황에 맞는 메뉴에서 이름 바꾸기를 선택하고 이름을 로 바꿉니다 SecurityTutorialsDatabase. 이렇게 하면 파일 이름이 변경되지 않고 데이터베이스가 SQL Server 자신을 식별하는 데 사용하는 이름만 변경됩니다.

데이터베이스 이름을 SecurityTutorialsDatabase로 바꿉니다.

그림 6: 데이터베이스 이름을 로 SecurityTutorialsDatabase바꿉니다(전체 크기 이미지를 보려면 클릭).

이 시점에서 데이터베이스 파일 localhost\InstanceName 의 서버 및 데이터베이스 이름( SecurityTutorials.mdf 각각 및 )을 SecurityTutorialsDatabase알고 있습니다. 이제 도구를 통해 애플리케이션 서비스를 설치할 준비가 되었습니다 aspnet_regsql.exe .

Application Services 설치

도구를 시작 aspnet_regsql.exe 하려면 시작 메뉴로 이동하여 실행을 선택합니다. 텍스트 상자에 를 입력 %WINDIR%\Microsoft.Net\Framework\v2.0.50727\aspnet_regsql.exe 하고 확인을 클릭합니다. 또는 Windows Explorer 사용하여 적절한 폴더로 드릴다운하고 파일을 두 번 클릭할 aspnet_regsql.exe 수 있습니다. 두 방법 모두 동일한 결과를 가져옵니다.

aspnet_regsql.exe 명령줄 인수 없이 도구를 실행하면 ASP.NET SQL Server 설치 마법사 그래픽 사용자 인터페이스가 시작됩니다. 마법사를 사용하면 지정된 데이터베이스에서 ASP.NET 애플리케이션 서비스를 쉽게 추가하거나 제거할 수 있습니다. 그림 7에 표시된 마법사의 첫 번째 화면에서 도구의 용도를 설명합니다.

ASP.NET SQL Server 설치 마법사를 사용하여 멤버 자격 스키마 추가

그림 7: ASP.NET SQL Server 설치 마법사를 사용하여 멤버 자격 스키마 추가(전체 크기 이미지를 보려면 클릭)

마법사의 두 번째 단계에서는 애플리케이션 서비스를 추가할지 또는 제거할 것인지를 묻습니다. 에 필요한 테이블, 뷰 및 저장 프로시저를 SqlMembershipProvider추가하려면 애플리케이션 서비스에 대한 SQL Server 구성 옵션을 선택합니다. 나중에 데이터베이스에서 이 스키마를 제거하려면 이 마법사를 다시 실행하지만 대신 기존 데이터베이스에서 애플리케이션 서비스 정보 제거 옵션을 선택합니다.

Application Services에 대한 SQL Server 구성 옵션을 선택합니다.

그림 8: Application Services에 대한 SQL Server 구성 옵션 선택(전체 크기 이미지를 보려면 클릭)

세 번째 단계에서는 서버 이름, 인증 정보 및 데이터베이스 이름 등 데이터베이스 정보를 묻는 메시지를 표시합니다. 이 자습서와 함께 데이터베이스를 추가하고 SecurityTutorials.mdf 에 데이터베이스를 App_Data연결 localhost\InstanceName하고 이름을 로 변경한 SecurityTutorialsDatabase경우 다음 값을 사용합니다.

  • 서버: localhost\InstanceName
  • Windows 인증
  • 데이터베이스: SecurityTutorialsDatabase

데이터베이스 정보 입력

그림 9: 데이터베이스 정보 입력(전체 크기 이미지를 보려면 클릭)

데이터베이스 정보를 입력한 후 다음을 클릭합니다. 마지막 단계에서는 수행할 단계를 요약합니다. 다음을 클릭하여 애플리케이션 서비스를 설치한 다음 마침을 클릭하여 마법사를 완료합니다.

참고

Management Studio를 사용하여 데이터베이스를 연결하고 데이터베이스 파일의 이름을 바꾼 경우 Visual Studio를 다시 열기 전에 데이터베이스를 분리하고 Management Studio를 닫아야 합니다. 데이터베이스를 SecurityTutorialsDatabase 분리하려면 데이터베이스 이름을 마우스 오른쪽 단추로 클릭하고 작업 메뉴에서 분리를 선택합니다.

마법사가 완료되면 Visual Studio로 돌아가 데이터베이스 Explorer 이동합니다. 테이블 폴더를 확장합니다. 이름이 접두 aspnet_사 로 시작하는 일련의 테이블이 표시됩니다. 마찬가지로 보기 및 저장 프로시저 폴더에서 다양한 보기 및 저장 프로시저를 찾을 수 있습니다. 이러한 데이터베이스 개체는 애플리케이션 서비스 스키마를 구성합니다. 3단계에서 멤버 자격 및 역할별 데이터베이스 개체를 살펴보겠습니다.

데이터베이스에 다양한 테이블, 뷰 및 저장 프로시저가 추가되었습니다.

그림 10: 데이터베이스에 다양한 테이블, 뷰 및 저장 프로시저가 추가되었습니다(전체 크기 이미지를 보려면 클릭).

참고

도구의 그래픽 사용자 인터페이스는 aspnet_regsql.exe 전체 애플리케이션 서비스 스키마를 설치합니다. 그러나 명령줄에서 실행할 aspnet_regsql.exe 때 설치(또는 제거)할 특정 애플리케이션 서비스 구성 요소를 지정할 수 있습니다. 따라서 및 SqlRoleProvider 공급자에 필요한 SqlMembershipProvider 테이블, 뷰 및 저장 프로시저만 추가하려면 명령줄에서 를 실행 aspnet_regsql.exe 합니다. 또는 에서 사용하는 aspnet_regsql.exeT-SQL 만들기 스크립트의 적절한 하위 집합을 수동으로 실행할 수 있습니다. 이러한 스크립트는 , , , InstallMembership.sqlInstallSqlState.sqlInstallRoles.sqlInstallProfile.sql, 등과 같은 InstallCommon.sql이름의 폴더에 있습니다.WINDIR%\Microsoft.Net\Framework\v2.0.50727\

이 시점에서 에 필요한 데이터베이스 개체를 SqlMembershipProvider만들었습니다. 그러나 멤버 자격 프레임워크는 (대, 예ActiveDirectoryMembershipProvider: )를 사용해야 SqlMembershipProvider 하며 SqlMembershipProvider 가 데이터베이스를 사용해야 SecurityTutorials 한다고 지시해야 합니다. 사용할 공급자를 지정하는 방법과 4단계에서 선택한 공급자의 설정을 사용자 지정하는 방법을 살펴보겠습니다. 먼저 방금 만든 데이터베이스 개체를 자세히 살펴보겠습니다.

3단계: 스키마의 핵심 테이블 살펴보기

ASP.NET 애플리케이션에서 멤버 자격 및 역할 프레임워크를 사용하는 경우 구현 세부 정보는 공급자가 캡슐화합니다. 이후 자습서에서는 .NET Framework Membership 및 클래스를 통해 이러한 프레임워크와 Roles 인터페이스합니다. 이러한 상위 수준 API를 사용하는 경우 실행되는 쿼리 또는 및 SqlRoleProvider에 의해 SqlMembershipProvider 수정된 테이블과 같은 하위 수준 세부 정보에 대해 걱정할 필요가 없습니다.

이 경우 2단계에서 만든 데이터베이스 스키마를 탐색하지 않고 멤버 자격 및 역할 프레임워크를 자신 있게 사용할 수 있습니다. 그러나 애플리케이션 데이터를 저장할 테이블을 만들 때 사용자 또는 역할과 관련된 엔터티를 만들어야 할 수 있습니다. 애플리케이션 데이터 테이블과 2단계에서 만든 테이블 간에 외래 키 제약 조건을 설정할 때 및 SqlRoleProvider 스키마를 숙 SqlMembershipProvider 지하는 데 도움이 됩니다. 또한 드문 경우지만 또는 클래스를 통 MembershipRoles 하지 않고 데이터베이스 수준에서 사용자 및 역할 저장소와 직접 인터페이스해야 할 수 있습니다.

사용자 저장소를 애플리케이션으로 분할

멤버 자격 및 역할 프레임워크는 여러 애플리케이션 간에 단일 사용자 및 역할 저장소를 공유할 수 있도록 설계되었습니다. 멤버 자격 또는 역할 프레임워크를 사용하는 ASP.NET 애플리케이션은 사용할 애플리케이션 파티션을 지정해야 합니다. 즉, 여러 웹 애플리케이션이 동일한 사용자 및 역할 저장소를 사용할 수 있습니다. 그림 11에서는 HRSite, CustomerSite 및 SalesSite의 세 가지 애플리케이션으로 분할된 사용자 및 역할 저장소를 보여 줍니다. 이 세 웹 애플리케이션에는 각각 고유한 사용자와 역할이 있지만 모두 사용자 계정 및 역할 정보를 동일한 데이터베이스 테이블에 물리적으로 저장합니다.

사용자 계정은 여러 애플리케이션에서 분할될 수 있습니다.

그림 11: 사용자 계정이 여러 애플리케이션에서 분할될 수 있음(전체 크기 이미지를 보려면 클릭)

테이블은 aspnet_Applications 이러한 파티션을 정의하는 것입니다. 데이터베이스를 사용하여 사용자 계정 정보를 저장하는 각 애플리케이션은 이 테이블의 행으로 표시됩니다. 테이블에는 aspnet_Applications , , ApplicationNameLoweredApplicationNameDescription열이 4개 있습니다ApplicationId.ApplicationId 는 형식 uniqueidentifier 이며 테이블의 기본 키 ApplicationName 입니다. 각 애플리케이션에 대해 고유한 사용자 친화적인 이름을 제공합니다.

다른 멤버 자격 및 역할 관련 테이블은 의 필드로 ApplicationId 다시 연결됩니다 aspnet_Applications. 예를 들어 aspnet_Users 각 사용자 계정에 대한 레코드를 포함하는 테이블에는 외래 키 필드인 ApplicationId 테이블의 ditto가 aspnet_Roles 있습니다. ApplicationId 이러한 테이블의 필드는 사용자 계정 또는 역할이 속한 애플리케이션 파티션을 지정합니다.

사용자 계정 정보 저장

사용자 계정 정보는 및 aspnet_Membership의 두 테이블에 aspnet_Users 저장됩니다. 테이블에는 aspnet_Users 필수 사용자 계정 정보를 포함하는 필드가 포함되어 있습니다. 가장 적절한 세 개의 열은 다음과 같습니다.

  • UserId
  • UserName
  • ApplicationId

UserId 는 기본 키(및 형식 uniqueidentifier)입니다. UserName 는 형식 nvarchar(256) 이며 암호와 함께 사용자의 자격 증명을 구성합니다. (사용자의 암호는 테이블에 저장됩니다 aspnet_Membership .) ApplicationId 는 의 특정 애플리케이션에 사용자 계정을 연결합니다 aspnet_Applications. 및 ApplicationId 열에 UserName 복합 UNIQUE 제약 조건이 있습니다. 이렇게 하면 지정된 애플리케이션에서 각 UserName이 고유하지만 다른 애플리케이션에서 동일한 UserName 를 사용할 수 있습니다.

테이블에는 aspnet_Membership 사용자의 암호, 이메일 주소, 마지막 로그인 날짜 및 시간 등과 같은 추가 사용자 계정 정보가 포함됩니다. 및 aspnet_Membership 테이블의 레코드 간에 일대일 대응이 aspnet_Users 있습니다. 이 관계는 테이블의 UserId 기본 키 역할을 하는 의 aspnet_Membership필드에 의해 보장됩니다. 테이블 aspnet_Membershipaspnet_Users 마찬가지로 에는 이 정보를 특정 애플리케이션 파티션에 연결하는 필드가 포함됩니다ApplicationId.

암호 보안

암호 정보는 테이블에 저장됩니다 aspnet_Membership . 를 SqlMembershipProvider 사용하면 다음 세 가지 기술 중 하나를 사용하여 데이터베이스에 암호를 저장할 수 있습니다.

  • 지우기 - 암호는 데이터베이스에 일반 텍스트로 저장됩니다. 이 옵션을 사용하는 것이 좋습니다. 데이터베이스가 손상된 경우( 백도어를 찾은 해커 또는 데이터베이스 액세스 권한이 있는 불만을 품은 직원에 의해) 모든 단일 사용자의 자격 증명이 제공됩니다.
  • 해시 - 암호는 단방향 해시 알고리즘과 임의로 생성된 솔트 값을 사용하여 해시됩니다. 이 해시된 값(솔트 포함)은 데이터베이스에 저장됩니다.
  • 암호화됨 - 암호화된 버전의 암호가 데이터베이스에 저장됩니다.

사용되는 암호 스토리지 기술은 에 Web.config지정된 설정에 SqlMembershipProvider 따라 달라집니다. 4단계에서 설정 사용자 지정 SqlMembershipProvider 을 살펴보겠습니다. 기본 동작은 암호의 해시를 저장하는 것입니다.

암호 저장을 담당하는 열은 , PasswordFormatPasswordSalt입니다Password. PasswordFormat 는 암호를 저장하는 데 사용되는 기술을 나타내는 형식 int 의 필드입니다. 0은 지우기, 1은 해시됨, 2는 Encrypted입니다. PasswordSalt 은 사용된 암호 스토리지 기술에 관계없이 임의로 생성된 문자열을 할당합니다. 의 값 PasswordSalt 은 암호의 해시를 계산할 때만 사용됩니다. 마지막으로, 열에는 Password 일반 텍스트 암호, 암호 해시 또는 암호화된 암호와 같은 실제 암호 데이터가 포함됩니다.

표 1에서는 MySecret 암호를 저장할 때 이러한 세 열이 다양한 스토리지 기술에 대해 어떤 모습일지 보여 줍니다. .

스토리지 기술<_o3a_p /> 암호<_o3a_p /> PasswordFormat<_o3a_p /> PasswordSalt<_o3a_p />
지우기 MySecret! 0 tTnkPlesqissc2y2SMEygA==
해시됨 2oXm6sZHWbTHFgjgkGQsc2Ec9ZM= 1 wFgjUfhdUFOCKQiI61vtiQ==
암호화됨 62RZgDvhxykkqsMchZ0Yly7HS6onhpaoCYaRxV8g0F4CW56OXUU3e7Inza9j9BKp 2 LSRzhGS/aa/oqAXGLHJNBw==

표 1: 암호 MySecret을 저장할 때 Password-Related 필드에 대한 예제 값입니다.

참고

에서 사용하는 SqlMembershipProvider 특정 암호화 또는 해시 알고리즘은 요소의 설정에 <machineKey> 따라 결정됩니다.

역할 및 역할 연결 저장

역할 프레임워크를 사용하면 개발자가 역할 집합을 정의하고 사용자가 어떤 역할에 속하는지 지정할 수 있습니다. 이 정보는 및 aspnet_UsersInRoles의 두 테이블을 aspnet_Roles 통해 데이터베이스에 캡처됩니다. 테이블의 aspnet_Roles 각 레코드는 특정 애플리케이션에 대한 역할을 나타냅니다. 표 aspnet_Rolesaspnet_Users 마찬가지로 테이블에는 토론과 관련한 세 개의 열이 있습니다.

  • RoleId
  • RoleName
  • ApplicationId

RoleId 는 기본 키(및 형식 uniqueidentifier)입니다. RoleNamenvarchar(256) 형식입니다. 그리고 ApplicationId 의 특정 애플리케이션 aspnet_Applications에 사용자 계정을 연결합니다. 및 ApplicationId 열에 RoleName 복합 UNIQUE 제약 조건이 있으므로 지정된 애플리케이션에서 각 역할 이름이 고유하도록 합니다.

테이블은 aspnet_UsersInRoles 사용자와 역할 간의 매핑 역할을 합니다. 및 RoleIdUserId 은 두 개뿐이며 함께 복합 기본 키를 구성합니다.

4단계: 공급자 지정 및 설정 사용자 지정

멤버 자격 및 역할 프레임워크와 같은 공급자 모델을 지원하는 모든 프레임워크에는 구현 세부 정보 자체가 부족하고 대신 공급자 클래스에 해당 책임을 위임합니다. Membership 프레임워크의 경우 클래스는 Membership 사용자 계정을 관리하기 위한 API를 정의하지만 사용자 저장소와 직접 상호 작용하지는 않습니다. 대신 클래스의 메서드는 Membership 구성된 공급자에게 요청을 전달합니다. 여기서는 를 사용합니다 SqlMembershipProvider. 클래스에서 메서드 Membership 중 하나를 호출할 때 멤버 자격 프레임워크는 호출을 에 위임하는 방법을 어떻게 알 수 SqlMembershipProvider있나요?

클래스에는 MembershipProviders Membership 프레임워크에서 사용할 수 있는 등록된 모든 공급자 클래스에 대한 참조가 포함된 속성이 있습니다. 등록된 각 공급자에는 연결된 이름과 형식이 있습니다. 이름은 컬렉션에서 특정 공급자 Providers 를 참조하는 인간 친화적인 방법을 제공하지만 형식은 공급자 클래스를 식별합니다. 또한 등록된 각 공급자에는 구성 설정이 포함될 수 있습니다. 멤버 자격 프레임워크에 대한 구성 설정에는 및 가 포함됩니다 PasswordFormatrequiresUniqueEmail. 에서 사용하는 구성 설정의 전체 목록은 표 2를 SqlMembershipProvider참조하세요.

Providers 속성의 콘텐츠는 웹 애플리케이션의 구성 설정을 통해 지정됩니다. 기본적으로 모든 웹 애플리케이션에는 형식SqlMembershipProvider의 공급자 AspNetSqlMembershipProvider 가 있습니다. 이 기본 멤버 자격 공급자는 에 machine.config 등록됩니다(에 %WINDIR%\Microsoft.Net\Framework\v2.0.50727\CONFIG있음).

<membership> 
 <providers>
 <add name="AspNetSqlMembershipProvider"
 type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" 
 connectionStringName="LocalSqlServer"
 enablePasswordRetrieval="false"
 enablePasswordReset="true"
 requiresQuestionAndAnswer="true"
 applicationName="/"
 requiresUniqueEmail="false"
 passwordFormat="Hashed"
 maxInvalidPasswordAttempts="5"
 minRequiredPasswordLength="7"
 minRequiredNonalphanumericCharacters="1"
 passwordAttemptWindow="10"
 passwordStrengthRegularExpression=""/>
 </providers> 
</membership>

위의 <membership> 태그와 같이 요소는 Membership 프레임워크에 대한 구성 설정을 정의하고 <providers> 자식 요소는 등록된 공급자를 지정합니다. 또는 요소를 사용하여 <add> 공급자를 추가하거나 <remove> 제거할 수 있습니다. 요소를 사용하여 <clear> 현재 등록된 모든 공급자를 제거합니다. 위의 machine.config 태그와 같이 형식의 SqlMembershipProvider공급자 AspNetSqlMembershipProvider 를 추가합니다.

type 특성 <add> 외에도 name 요소에는 다양한 구성 설정에 대한 값을 정의하는 특성이 포함되어 있습니다. 표 2에는 각각에 대한 설명과 함께 사용 가능한 SqlMembershipProvider특정 구성 설정이 나열되어 있습니다.

참고

표 2에 기록된 모든 기본값은 클래스에 정의된 기본값을 SqlMembershipProvider 참조합니다. 의 모든 구성 설정 AspNetSqlMembershipProvider 이 클래스의 SqlMembershipProvider 기본값에 해당하는 것은 아닙니다. 예를 들어 멤버 자격 공급자에 지정되지 않은 경우 설정은 requiresUniqueEmail 기본적으로 true로 설정됩니다. 그러나 는 AspNetSqlMembershipProvider 값을 명시적으로 지정하여 이 기본값을 재정의 false합니다.

설정<_o3a_p /> 설명<_o3a_p />
ApplicationName Membership 프레임워크를 사용하면 단일 사용자 저장소를 여러 애플리케이션에서 분할할 수 있습니다. 이 설정은 멤버 자격 공급자가 사용하는 애플리케이션 파티션의 이름을 나타냅니다. 이 값을 명시적으로 지정하지 않으면 런타임 시 애플리케이션의 가상 루트 경로 값으로 설정됩니다.
commandTimeout SQL 명령 시간 제한 값(초)을 지정합니다. 기본값은 30입니다.
connectionStringName 사용자 저장소 데이터베이스에 연결하는 데 사용할 요소의 <connectionStrings> 연결 문자열 이름입니다. 이 값은 필수입니다.
description 등록된 공급자에 대한 사용자에게 친숙한 설명을 제공합니다.
enablePasswordRetrieval 사용자가 잊어버린 암호를 검색할 수 있는지 여부를 지정합니다. 기본값은 false입니다.
enablePasswordReset 사용자가 암호를 재설정할 수 있는지 여부를 나타냅니다. 기본값은 true입니다.
maxInvalidPasswordAttempts 사용자가 잠기기 전에 지정된 passwordAttemptWindow 동안 지정된 사용자에 대해 발생할 수 있는 최대 로그인 시도 횟수입니다. 기본값은 5입니다.
minRequiredNonalphanumericCharacters 사용자의 암호에 표시되어야 하는 영숫자가 아닌 최소 문자 수입니다. 이 값은 0에서 128 사이여야 합니다. 기본값은 1입니다.
minRequiredPasswordLength 암호에 필요한 최소 문자 수입니다. 이 값은 0에서 128 사이여야 합니다. 기본값은 7입니다.
name 등록된 공급자의 이름입니다. 이 값은 필수입니다.
passwordAttemptWindow 실패한 로그인 시도가 추적되는 시간(분)입니다. 사용자가 이 지정된 창 내에서 잘못된 로그인 자격 증명 시간을 제공하면 해당 자격 증명 maxInvalidPasswordAttempts 이 잠깁니다. 기본값은 10입니다.
PasswordFormat 암호 스토리지 형식: Clear, Hashed또는 Encrypted. 기본값은 Hashed입니다.
passwordStrengthRegularExpression 제공되는 경우 이 정규식은 새 계정을 만들거나 암호를 변경할 때 사용자가 선택한 암호의 강도를 평가하는 데 사용됩니다. 기본값은 빈 문자열입니다.
requiresQuestionAndAnswer 사용자가 암호를 검색하거나 재설정할 때 보안 질문에 답해야 하는지 여부를 지정합니다. 기본값은 true입니다.
requiresUniqueEmail 지정된 애플리케이션 파티션의 모든 사용자 계정에 고유한 이메일 주소가 있어야 하는지 여부를 나타냅니다. 기본값은 true입니다.
type 공급자의 형식을 지정합니다. 이 값은 필수입니다.

표 2: 멤버 자격 및 SqlMembershipProvider 구성 설정

외에도 AspNetSqlMembershipProvider다른 멤버 자격 공급자는 파일에 유사한 태그 Web.config 를 추가하여 애플리케이션별로 등록할 수 있습니다.

참고

역할 프레임워크는 거의 동일한 방식으로 작동합니다. 에 기본 등록된 역할 공급자 machine.config 가 있으며 등록된 공급자는 의 애플리케이션별로 Web.config사용자 지정할 수 있습니다. 향후 자습서에서는 역할 프레임워크 및 해당 구성 태그를 자세히 살펴보겠습니다.

SqlMembershipProvider설정 사용자 지정

기본값 SqlMembershipProvider (AspNetSqlMembershipProvider)에는 특성이 connectionStringName 로 설정되어 있습니다 LocalSqlServer. 공급자와 AspNetSqlMembershipProvider 마찬가지로 연결 문자열 이름은 LocalSqlServermachine.config정의됩니다.

<connectionStrings> 
 <add name="LocalSqlServer" 
 connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true" 
 providerName="System.Data.SqlClient"/> 
</connectionStrings>

여기서 볼 수 있듯이 이 연결 문자열 | 에 있는 SQL 2005 Express Edition 데이터베이스를 정의합니다.DataDirectory|aspnetdb.mdf. 문자열 |DataDirectory| 는 런타임에 디렉터리를 가리키 ~/App_Data/ 도록 변환되므로 데이터베이스 경로 |DataDirectory|aspnetdb.mdf 로 변환됩니다 ~/App_Data/aspnet.mdf.

애플리케이션의 Web.config 파일에 멤버 자격 공급자 정보를 지정하지 않은 경우 애플리케이션은 기본 등록된 멤버 자격 공급자 를 AspNetSqlMembershipProvider사용합니다. 데이터베이스가 ~/App_Data/aspnet.mdf 없으면 ASP.NET 런타임에서 자동으로 데이터베이스를 만들고 애플리케이션 서비스 스키마를 추가합니다. 그러나 데이터베이스를 사용하지 aspnet.mdf 않고 2단계에서 만든 데이터베이스를 SecurityTutorials.mdf 사용하려고 합니다. 이 수정은 다음 두 가지 방법 중 하나로 수행할 수 있습니다.

  • 에 대한 값을 지정합니다.LocalSqlServer연결 문자열 이름입니다Web.config. 에서 Web.config연결 문자열 이름 값을 덮어쓰 LocalSqlServer 면 기본 등록된 멤버 자격 공급자(AspNetSqlMembershipProvider)를 사용하고 데이터베이스에서 SecurityTutorials.mdf 올바르게 작동할 수 있습니다. 이 방법은 에서 지정 AspNetSqlMembershipProvider한 구성 설정에 만족하는 경우 괜찮습니다. 이 기술에 대한 자세한 내용은 Scott Guthrie의 블로그 게시물, SQL Server 2000 또는 SQL Server 2005를 사용하도록 ASP.NET 2.0 Application Services 구성을 참조하세요.
  • 형식 SqlMembershipProvider의 등록된 새 공급자 추가및 구성connectionStringName를 가리키SecurityTutorials.mdf도록 설정데이터베이스. 이 방법은 데이터베이스 연결 문자열 외에도 다른 구성 속성을 사용자 지정하려는 시나리오에서 유용합니다. 내 프로젝트에서는 유연성과 가독성 때문에 항상 이 방법을 사용합니다.

데이터베이스를 참조 SecurityTutorials.mdf 하는 등록된 새 공급자를 추가하려면 먼저 의 섹션에서 Web.config적절한 연결 문자열 값을 <connectionStrings> 추가해야 합니다. 다음 태그는 폴더의 SQL Server 2005 Express Edition 데이터베이스 App_Data 를 참조하는 라는 SecurityTutorialsConnectionString 새 연결 문자열 SecurityTutorials.mdf 추가합니다.

<configuration>
 <connectionStrings>
 <add name="SecurityTutorialsConnectionString" 
 connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\SecurityTutorials.mdf;Integrated Security=True;User Instance=True" 
 providerName="System.Data.SqlClient"/>
 </connectionStrings> 
 <system.web>
 ... Configuration markup removed for brevity ...  </system.web>
</configuration>

참고

대체 데이터베이스 파일을 사용하는 경우 필요에 따라 연결 문자열 업데이트합니다. 올바른 연결 문자열 구성하는 방법에 대한 자세한 내용은 ConnectionStrings.com 참조하세요.

다음으로, 다음 멤버 자격 구성 태그를 파일에 추가합니다 Web.config . 이 태그는 라는 SecurityTutorialsSqlMembershipProvider새 공급자를 등록합니다.

<configuration>
 <connectionStrings>
 <add name="SecurityTutorialsConnectionString" 
 connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\SecurityTutorials.mdf;Integrated Security=True;User Instance=True" 
 providerName="System.Data.SqlClient"/>
 </connectionStrings> 
 <system.web>
 <membership defaultProvider="SecurityTutorialsSqlMembershipProvider">
 <providers>
 <!-- Add a customized SqlMembershipProvider --> 
 <add name="SecurityTutorialsSqlMembershipProvider" 
 type="System.Web.Security.SqlMembershipProvider"
 connectionStringName="SecurityTutorialsConnectionString"
 enablePasswordRetrieval="false"
 enablePasswordReset="true"
 requiresQuestionAndAnswer="true"
 applicationName="SecurityTutorials"
 requiresUniqueEmail="true"
 passwordFormat="Hashed"
 maxInvalidPasswordAttempts="5"
 minRequiredPasswordLength="7"
 minRequiredNonalphanumericCharacters="1"
 passwordAttemptWindow="10"
 passwordStrengthRegularExpression=""/>
 </providers>
 </membership>
 ... Configuration markup removed for brevity ... 
 </system.web>
</configuration>

공급자를 등록하는 SecurityTutorialsSqlMembershipProvider 것 외에도 위의 태그는 를 기본 공급자로 정의합니다 SecurityTutorialsSqlMembershipProvider (요소의 defaultProvider 특성을 <membership> 통해). 멤버 자격 프레임워크에는 여러 개의 등록된 공급자가 있을 수 있습니다. AspNetSqlMembershipProvider 는 의 machine.config첫 번째 공급자로 등록되므로 달리 명시하지 않는 한 기본 공급자로 사용됩니다.

현재 애플리케이션에는 및 SecurityTutorialsSqlMembershipProvider라는 두 개의 등록된 공급자가 있습니다AspNetSqlMembershipProvider. 그러나 공급자를 SecurityTutorialsSqlMembershipProvider 등록하기 전에 요소 바로 앞에 <add> 요소를 추가하여 이전에 등록된 모든 공급자를 <clear /> 지울 수 있었습니다. 이렇게 하면 등록된 공급자 목록에서 가 지 AspNetSqlMembershipProvider 워지므로 가 SecurityTutorialsSqlMembershipProvider 유일한 등록된 멤버 자격 공급자가 됩니다. 이 방법을 사용한 경우 유일한 등록된 멤버 자격 공급자이므로 를 기본 공급자로 표시 SecurityTutorialsSqlMembershipProvider 할 필요가 없습니다. 사용에 <clear />대한 자세한 내용은 공급자를 추가할 때 사용을 <clear /> 참조하세요.

connectionStringName 설정은 SecurityTutorialsSqlMembershipProvider방금 추가 SecurityTutorialsConnectionString 된 연결 문자열 이름을 참조하며 해당 applicationName 설정은 SecurityTutorials 값으로 설정되었습니다. 또한 설정이 requiresUniqueEmail 로 설정 true되었습니다. 다른 모든 구성 옵션은 의 AspNetSqlMembershipProvider값과 동일합니다. 원하는 경우 여기에서 구성을 자유롭게 수정할 수 있습니다. 예를 들어 영숫자가 아닌 두 문자를 요구하거나 암호 길이를 7자가 아닌 8자로 늘려 암호 강도를 강화할 수 있습니다.

참고

Membership 프레임워크를 사용하면 단일 사용자 저장소를 여러 애플리케이션에서 분할할 수 있습니다. 멤버 자격 공급자의 applicationName 설정은 공급자가 사용자 저장소로 작업할 때 사용하는 애플리케이션을 나타냅니다. 가 명시적으로 설정되지 않은 경우 applicationName 런타임에 웹 애플리케이션의 가상 루트 경로에 할당되므로 구성 설정에 대한 applicationName 값을 명시적으로 설정하는 것이 중요합니다. 애플리케이션의 가상 루트 경로가 변경되지 않는 한 잘 작동하지만 애플리케이션을 다른 경로 applicationName 로 이동하면 설정도 변경됩니다. 이 경우 멤버 자격 공급자는 이전에 사용한 것과 다른 애플리케이션 파티션으로 작업을 시작합니다. 이동하기 전에 만든 사용자 계정은 다른 애플리케이션 파티션에 상주하며 해당 사용자는 더 이상 사이트에 로그인할 수 없습니다. 이 문제에 대한 자세한 내용은 ASP.NET 2.0 멤버 자격 및 기타 공급자를 구성할 때 항상 속성 설정을 applicationName 참조하세요.

요약

이 시점에서 구성된 애플리케이션 서비스(SecurityTutorials.mdf)가 있는 데이터베이스가 있고 멤버 자격 프레임워크가 방금 등록한 공급자를 사용하도록 웹 애플리케이션을 SecurityTutorialsSqlMembershipProvider 구성했습니다. 이 등록된 공급자는 형식 SqlMembershipProvider 이며 해당 connectionStringName 공급자가 적절한 연결 문자열()로SecurityTutorialsConnectionString 설정되고 해당 값이 applicationName 명시적으로 설정됩니다.

이제 애플리케이션에서 멤버 자격 프레임워크를 사용할 준비가 되었습니다. 다음 자습서에서는 새 사용자 계정을 만드는 방법을 살펴봅니다. 그런 다음, 사용자를 인증하고, 사용자 기반 권한 부여를 수행하고, 데이터베이스에 추가 사용자 관련 정보를 저장하는 방법에 대해 알아봅니다.

행복한 프로그래밍!

추가 정보

이 자습서에서 설명하는 topics 대한 자세한 내용은 다음 리소스를 참조하세요.

이 자습서에 포함된 항목에 대한 비디오 교육

저자 정보

여러 ASP/ASP.NET 책의 저자이자 4GuysFromRolla.com 창립자인 Scott Mitchell은 1998년부터 Microsoft 웹 기술을 연구해 왔습니다. Scott은 독립 컨설턴트, 트레이너 및 작가로 일합니다. 그의 최신 책은 샘스 티치 유어셀프 ASP.NET 24시간 만에 2.0입니다. Scott은 에서 mitchell@4guysfromrolla.com 또는 에서 자신의 블로그 http://ScottOnWriting.NET를 통해 연락할 수 있습니다.

특별 감사

이 자습서 시리즈는 많은 유용한 검토자가 검토했습니다. 이 자습서의 수석 검토자는 Alicja Maziarz였습니다. 예정된 MSDN 문서를 검토하는 데 관심이 있으신가요? 그렇다면 에 줄을 놓습니다 mitchell@4GuysFromRolla.com.