멤버 자격 사용자 저장소에 대해 사용자 자격 증명의 유효성 검사(C#)

작성자 : Scott Mitchell

참고

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

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

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

이 자습서에서는 프로그래밍 방식의 수단과 로그인 컨트롤을 모두 사용하여 멤버 자격 증명 사용자 저장소에 대해 사용자 자격 증명의 유효성을 검사하는 방법을 검토합니다. 로그인 컨트롤의 모양과 동작을 사용자 지정하는 방법도 살펴보겠습니다.

소개

이전 자습서에서는 멤버 자격 프레임워크에서 새 사용자 계정을 만드는 방법을 살펴보았습니다. 먼저 클래스의 CreateUser 메서드를 통해 Membership 프로그래밍 방식으로 사용자 계정을 만드는 방법을 살펴본 다음 CreateUserWizard 웹 컨트롤을 사용하여 검사했습니다. 그러나 로그인 페이지는 현재 사용자 이름 및 암호 쌍의 하드 코드된 목록에 대해 제공된 자격 증명의 유효성을 검사합니다. 멤버 자격 프레임워크의 사용자 저장소에 대한 자격 증명의 유효성을 검사하도록 로그인 페이지의 논리를 업데이트해야 합니다.

사용자 계정을 만드는 것과 마찬가지로 자격 증명은 프로그래밍 방식으로 또는 선언적으로 유효성을 검사할 수 있습니다. 멤버 자격 API에는 사용자 저장소에 대해 사용자 자격 증명의 유효성을 프로그래밍 방식으로 검사하는 메서드가 포함되어 있습니다. 또한 ASP.NET 로그인 웹 컨트롤과 함께 제공되어 사용자 이름 및 암호에 대한 텍스트 상자와 로그인 단추가 있는 사용자 인터페이스를 렌더링합니다.

이 자습서에서는 프로그래밍 방식의 수단과 로그인 컨트롤을 모두 사용하여 멤버 자격 증명 사용자 저장소에 대해 사용자 자격 증명의 유효성을 검사하는 방법을 검토합니다. 로그인 컨트롤의 모양과 동작을 사용자 지정하는 방법도 살펴보겠습니다. 그럼 시작하겠습니다.

1단계: 멤버 자격 사용자 저장소에 대한 자격 증명 유효성 검사

양식 인증을 사용하는 웹 사이트의 경우 사용자는 로그인 페이지를 방문하여 자격 증명을 입력하여 웹 사이트에 로그온합니다. 그런 다음 이러한 자격 증명을 사용자 저장소와 비교합니다. 유효한 경우 사용자에게 방문자의 ID와 신뢰성을 나타내는 보안 토큰인 양식 인증 티켓이 부여됩니다.

멤버 자격 프레임워크에 대해 사용자의 유효성을 검사하려면 클래스의 ValidateUser 메서드Membership 사용합니다. 메서드는 ValidateUserpassword 의 두 입력 매개 변수 username 를 사용하고 자격 증명이 유효한지 여부를 나타내는 부울 값을 반환합니다. 이전 자습서에서 검사한 메서드와 CreateUser 마찬가지로 메서드는 ValidateUser 구성된 멤버 자격 공급자에게 실제 유효성 검사를 위임합니다.

SqlMembershipProvider 저장 프로시저를 통해 지정된 사용자의 암호를 가져와 제공된 자격 증명의 유효성을 aspnet_Membership_GetPasswordWithFormat 검사합니다. 는 SqlMembershipProvider 지우기, 암호화 또는 해시된 세 가지 형식 중 하나를 사용하여 사용자의 암호를 저장합니다. 저장 프로시저는 aspnet_Membership_GetPasswordWithFormat 암호를 원시 형식으로 반환합니다. 암호화되거나 해시된 암호의 경우 는 SqlMembershipProvider 메서드에 ValidateUser 전달된 값을 해당 암호화 또는 해시된 상태로 변환 password 한 다음 데이터베이스에서 반환된 값과 비교합니다. 데이터베이스에 저장된 암호가 사용자가 입력한 형식의 암호와 일치하는 경우 자격 증명이 유효합니다.

멤버 자격 프레임워크 사용자 저장소에 대해 제공된 자격 증명의 유효성을 검사하도록 로그인 페이지(~/Login.aspx)를 업데이트해 보겠습니다. 이 로그인 페이지를 양식 인증 개요 자습서에서 다시 만들어 사용자 이름과 암호에 대한 두 개의 TextBox, 기억 확인란 및 로그인 단추가 있는 인터페이스를 만들었습니다(그림 1 참조). 코드는 하드 코딩된 사용자 이름 및 암호 쌍 목록(Scott/password, Jisun/password 및 Sam/password)에 대해 입력한 자격 증명의 유효성을 검사합니다.

로그인 페이지의 인터페이스에는 두 개의 TextBox, CheckBoxList 및 단추가 포함됩니다.

그림 1: 로그인 페이지의 인터페이스에는 두 개의 TextBox, CheckBoxList 및 단추가 포함되어 있습니다(전체 크기 이미지를 보려면 클릭).

로그인 페이지의 사용자 인터페이스는 변경되지 않은 상태로 유지될 수 있지만 로그인 단추의 Click 이벤트 처리기를 멤버 자격 프레임워크 사용자 저장소에 대해 사용자의 유효성을 검사하는 코드로 바꿔야 합니다. 다음과 같이 코드가 표시되도록 이벤트 처리기를 업데이트합니다.

protected void LoginButton_Click(object sender, EventArgs e)
{
    // Validate the user against the Membership framework user store
    if (Membership.ValidateUser(UserName.Text, Password.Text))
    {
        // Log the user into the site
        FormsAuthentication.RedirectFromLoginPage(UserName.Text, RememberMe.Checked);
    }
    // If we reach here, the user's credentials were invalid
    InvalidCredentialsMessage.Visible = true;
}

이 코드는 매우 간단합니다. 먼저 메서드를 호출하여 Membership.ValidateUser 제공된 사용자 이름 및 암호를 전달합니다. 해당 메서드가 true를 반환하면 사용자는 클래스의 RedirectFromLoginPage 메서드를 FormsAuthentication 통해 사이트에 로그인됩니다. (에서 설명한 대로양식 인증 개요 자습서에서는 FormsAuthentication.RedirectFromLoginPage 양식 인증 티켓을 만든 다음 사용자를 적절한 페이지로 리디렉션합니다.) 그러나 InvalidCredentialsMessage 자격 증명이 유효하지 않으면 레이블이 표시되어 사용자에게 사용자 이름 또는 암호가 잘못되었음을 알립니다.

이제 모든 작업을 마쳤습니다.

로그인 페이지가 예상대로 작동하는지 테스트하려면 이전 자습서에서 만든 사용자 계정 중 하나를 사용하여 로그인을 시도합니다. 또는 아직 계정을 만들지 않은 경우 계속 진행하여 페이지에서 계정을 만듭니다 ~/Membership/CreatingUserAccounts.aspx .

참고

사용자가 자격 증명을 입력하고 로그인 페이지 양식을 제출하면 암호를 포함한 자격 증명이 인터넷을 통해 일반 텍스트로 웹 서버로 전송됩니다. 즉, 네트워크 트래픽을 스니핑하는 모든 해커가 사용자 이름과 암호를 볼 수 있습니다. 이를 방지하려면 SSL(Secure Socket Layers)을 사용하여 네트워크 트래픽을 암호화해야 합니다. 이렇게 하면 자격 증명(및 전체 페이지의 HTML 태그)이 브라우저를 떠나는 순간부터 웹 서버에서 수신될 때까지 암호화됩니다.

멤버 자격 프레임워크에서 잘못된 로그인 시도를 처리하는 방법

방문자가 로그인 페이지에 도달하고 자격 증명을 제출하면 브라우저에서 로그인 페이지에 HTTP 요청을 합니다. 자격 증명이 유효한 경우 HTTP 응답에는 쿠키에 인증 티켓이 포함됩니다. 따라서 사이트에 침입하려는 해커는 유효한 사용자 이름과 암호 추측을 사용하여 로그인 페이지에 HTTP 요청을 완전히 보내는 프로그램을 만들 수 있습니다. 암호 추측이 올바르면 로그인 페이지에서 인증 티켓 쿠키를 반환합니다. 이때 프로그램에서 유효한 사용자 이름/암호 쌍을 발견했음을 알 수 있습니다. 무차별 암호 대입을 통해 이러한 프로그램은 특히 암호가 약한 경우 사용자의 암호를 발견할 수 있습니다.

이러한 무차별 암호 대입 공격을 방지하기 위해 멤버 자격 프레임워크는 특정 기간 내에 특정 수의 실패한 로그인 시도가 있는 경우 사용자를 잠가줍니다. 정확한 매개 변수는 다음 두 멤버 자격 공급자 구성 설정을 통해 구성할 수 있습니다.

  • maxInvalidPasswordAttempts - 계정이 잠기기 전 기간 내에 사용자에게 허용되는 잘못된 암호 시도 횟수를 지정합니다. 기본값은 5입니다.
  • passwordAttemptWindow - 지정된 수의 잘못된 로그인 시도로 인해 계정이 잠기게 되는 기간(분)을 나타냅니다. 기본값은 10입니다.

사용자가 잠긴 경우 관리자가 계정 잠금을 해제할 때까지 로그인할 수 없습니다. 사용자가 잠기면 유효한 자격 증명이 ValidateUser 제공되더라도 메서드는 항상 를 반환 false합니다. 이 동작은 해커가 무차별 암호 대입 방법을 통해 사이트에 침입할 가능성을 줄이지만 단순히 암호를 잊어버렸거나 실수로 Caps Lock이 켜졌거나 잘못된 입력 일을 하는 유효한 사용자를 잠글 수 있습니다.

아쉽게도 사용자 계정의 잠금을 해제하기 위한 기본 제공 도구는 없습니다. 계정의 잠금을 해제하기 위해 데이터베이스를 직접 수정하거나 적절한 사용자 계정에 대한 테이블의 IsLockedOutaspnet_Membership 필드를 변경하거나 잠금 해제 옵션이 있는 잠긴 계정을 나열하는 웹 기반 인터페이스를 만들 수 있습니다. 향후 자습서에서는 일반적인 사용자 계정 및 역할 관련 작업을 수행하기 위한 관리 인터페이스 만들기를 살펴보겠습니다.

참고

메서드의 ValidateUser 한 가지 단점은 제공된 자격 증명이 유효하지 않은 경우 이유에 대한 설명을 제공하지 않는다는 것입니다. 사용자 저장소에 일치하는 사용자 이름/암호 쌍이 없거나 사용자가 아직 승인되지 않았거나 사용자가 잠겨 있기 때문에 자격 증명이 유효하지 않을 수 있습니다. 4단계에서는 로그인 시도가 실패할 때 사용자에게 더 자세한 메시지를 표시하는 방법을 알아봅니다.

2단계: 로그인 웹 컨트롤을 통해 자격 증명 수집

로그인 웹 컨트롤양식 인증 개요 자습서에서 만든 것과 매우 유사한 기본 사용자 인터페이스를 렌더링합니다. 로그인 컨트롤을 사용하면 방문자의 자격 증명을 수집하기 위해 인터페이스를 만들어야 하는 작업이 절약됩니다. 또한 로그인 컨트롤은 제출된 자격 증명이 유효하다고 가정하여 사용자를 자동으로 로그인하므로 코드를 작성할 필요가 없습니다.

수동으로 만든 인터페이스 및 코드를 로그인 컨트롤로 대체하여 를 업데이트 Login.aspx해 보겠습니다. 먼저 에서 기존 태그 및 코드를 제거합니다 Login.aspx. 완전히 삭제하거나 단순히 주석 처리할 수 있습니다. 선언적 태그를 주석으로 처리하려면 및 --%> 구분 기호로 <%-- 묶습니다. 이러한 구분 기호를 수동으로 입력하거나 그림 2에서 볼 수 있듯이 주석 처리할 텍스트를 선택한 다음 도구 모음에서 선택한 줄 주석 처리 아이콘을 클릭할 수 있습니다. 마찬가지로 선택한 줄 주석 처리 아이콘을 사용하여 코드 숨김 클래스에서 선택한 코드를 주석 처리할 수 있습니다.

Login.aspx에서 기존 선언적 태그 및 소스 코드 주석 처리

그림 2: 에서 기존 선언적 태그 및 소스 코드 Login.aspx 주석 처리(전체 크기 이미지를 보려면 클릭)

참고

Visual Studio 2005에서 선언적 태그를 볼 때 선택한 줄 주석 처리 아이콘을 사용할 수 없습니다. Visual Studio 2008을 사용하지 않는 경우 및 --%> 구분 기호를 <%-- 수동으로 추가해야 합니다.

그런 다음 도구 상자의 로그인 컨트롤을 페이지로 끌어서 해당 ID 속성을 로 myLogin설정합니다. 이 시점에서 화면은 그림 3과 유사하게 표시됩니다. 로그인 컨트롤의 기본 인터페이스에는 사용자 이름 및 암호에 대한 TextBox 컨트롤, 다음에 CheckBox에 기억하기, 로그인 단추가 포함됩니다. 두 TextBox에 대한 컨트롤도 RequiredFieldValidator 있습니다.

페이지에 로그인 컨트롤 추가

그림 3: 페이지에 로그인 컨트롤 추가(전체 크기 이미지를 보려면 클릭)

다 됐습니다! 로그인 컨트롤의 로그인 단추를 클릭하면 포스트백이 발생하고 로그인 컨트롤이 메서드를 Membership.ValidateUser 호출하여 입력한 사용자 이름과 암호를 전달합니다. 자격 증명이 유효하지 않으면 로그인 컨트롤에 이러한 메시지가 표시됩니다. 그러나 자격 증명이 유효한 경우 로그인 컨트롤은 양식 인증 티켓을 만들고 사용자를 적절한 페이지로 리디렉션합니다.

로그인 컨트롤은 4가지 요소를 사용하여 적절한 페이지를 결정하여 성공적인 로그인 시 사용자를 리디렉션합니다.

  • 로그인 컨트롤이 양식 인증 구성에서 설정하여 loginUrl 정의된 대로 로그인 페이지에 있는지 여부입니다. 이 설정의 기본값은 입니다. Login.aspx
  • querystring 매개 변수의 ReturnUrl 존재 여부
  • 로그인 컨트롤의 DestinationUrl 속성
  • defaultUrl 폼 인증 구성 설정에 지정된 값입니다. 이 설정의 기본값은 입니다.Default.aspx

그림 4에서는 로그인 컨트롤이 이러한 네 가지 매개 변수를 사용하여 적절한 페이지 결정에 도달하는 방법을 보여 줍니다.

로그인 컨트롤은 네 개의 매개 변수를 사용하여 적절한 페이지 결정에 도달합니다.

그림 4: 페이지에 로그인 컨트롤 추가(전체 크기 이미지를 보려면 클릭)

잠시 시간을 내어 브라우저를 통해 사이트를 방문하고 멤버 자격 프레임워크에서 기존 사용자로 로그인하여 로그인 컨트롤을 테스트합니다.

로그인 컨트롤의 렌더링된 인터페이스는 매우 구성 가능합니다. 모양에 영향을 주는 여러 속성이 있습니다. 또한 로그인 컨트롤을 템플릿으로 변환하여 사용자 인터페이스 요소의 레이아웃을 정확하게 제어할 수 있습니다. 이 단계의 나머지 부분에서는 모양과 레이아웃을 사용자 지정하는 방법을 살펴봅니다.

로그인 컨트롤의 모양 사용자 지정

로그인 컨트롤의 기본 속성 설정은 사용자 이름 및 암호 입력에 대한 제목(로그인), TextBox 및 레이블 컨트롤, 다음에 CheckBox 및 로그인 단추를 사용하여 사용자 인터페이스를 렌더링합니다. 이러한 요소의 모양은 모두 로그인 컨트롤의 다양한 속성을 통해 구성할 수 있습니다. 또한 새 사용자 계정을 만들기 위한 페이지 링크와 같은 추가 사용자 인터페이스 요소는 속성 또는 두 개를 설정하여 추가할 수 있습니다.

잠시 시간을 내어 로그인 컨트롤의 모양을 정리해 보겠습니다. Login.aspx 페이지에 이미 로그인이라는 텍스트가 있으므로 로그인 컨트롤의 제목은 불필요합니다. 따라서 로그인 컨트롤의 제목을 TitleText 제거하려면 속성 값을 지웁니다.

사용자 이름: 및 암호: 두 TextBox 컨트롤의 왼쪽에 있는 레이블은 각각 및 PasswordLabelText 속성을 통해 UserNameLabelText 사용자 지정할 수 있습니다. 사용자 이름: 레이블을 Username:을 읽도록 변경해 보겠습니다. Label 및 TextBox 스타일은 각각 및 TextBoxStyle 속성을 통해 LabelStyle 구성할 수 있습니다.

다음에 CheckBox의 Text 속성을 로그인 컨트롤 RememberMeText property의 를 통해 설정할 수 있으며 기본 확인 상태는 를 통해 RememberMeSet property 구성할 수 있습니다(기본값은 False). 다음번에 RememberMeSet 기억 확인란이 기본적으로 선택되도록 속성을 True로 설정합니다.

로그인 컨트롤은 사용자 인터페이스 컨트롤의 레이아웃을 조정하기 위한 두 가지 속성을 제공합니다. 은 TextLayout property 사용자 이름: 및 암호: 레이블이 해당 TextBox의 왼쪽에 표시되는지(기본값) 위에 표시되는지 여부를 나타냅니다. 은 Orientation property 사용자 이름 및 암호 입력이 세로(다른 위) 또는 가로로 배치되는지 여부를 나타냅니다. 이 두 속성을 기본값으로 설정해 두겠습니다. 그러나 이러한 두 속성을 기본값이 아닌 값으로 설정하여 결과 효과를 확인하는 것이 좋습니다.

참고

다음 섹션에서는 로그인 컨트롤의 레이아웃 구성에서 템플릿을 사용하여 레이아웃 컨트롤의 사용자 인터페이스 요소의 정확한 레이아웃을 정의하는 방법을 살펴봅니다.

및 속성을 아직 등록되지 않음으로 설정 CreateUserText 하여 로그인 컨트롤의 속성 설정을 래핑합니다.CreateUserUrl 계정을 만듭니다! 및 ~/Membership/CreatingUserAccounts.aspx은 각각 입니다. 그러면 이전 자습서에서 만든 페이지를 가리키는 로그인 컨트롤의 인터페이스에 하이퍼링크가 추가됩니다. 로그인 컨트롤과 HelpPageTextHelpPageUrl 속성PasswordRecoveryTextPasswordRecoveryUrl 속성 은 동일한 방식으로 작동하여 도움말 페이지 및 암호 복구 페이지에 대한 링크를 렌더링합니다.

이러한 속성을 변경한 후 로그인 컨트롤의 선언적 태그 및 모양은 그림 5에 표시된 것과 유사하게 표시됩니다.

로그인 컨트롤의 속성 값에 따라 모양이 지정됩니다.

그림 5: 로그인 컨트롤의 속성 값이 모양을 지시합니다(전체 크기 이미지를 보려면 클릭).

로그인 컨트롤의 레이아웃 구성

로그인 웹 컨트롤의 기본 사용자 인터페이스는 HTML <table>에 인터페이스를 배치합니다. 그러나 렌더링된 출력을 보다 세밀하게 제어해야 하는 경우 어떻게 해야 할까요? 을 일련의 <div> 태그로 바꾸고 <table> 싶을 수도 있습니다. 또는 애플리케이션에 인증을 위한 추가 자격 증명이 필요한 경우 어떻게 해야 할까요? 대부분의 금융 웹 사이트는 instance 사용자 이름 및 암호뿐만 아니라 PIN(개인 식별 번호) 또는 기타 식별 정보를 제공해야 합니다. 이유가 무엇이든 간에 로그인 컨트롤을 템플릿으로 변환하여 인터페이스의 선언적 태그를 명시적으로 정의할 수 있습니다.

추가 자격 증명을 수집하도록 로그인 컨트롤을 업데이트하려면 다음 두 가지 작업을 수행해야 합니다.

  1. 추가 자격 증명을 수집하도록 웹 컨트롤을 포함하도록 로그인 컨트롤의 인터페이스를 업데이트합니다.
  2. 사용자가 사용자 이름과 암호가 유효하고 추가 자격 증명이 유효한 경우에만 인증되도록 로그인 컨트롤의 내부 인증 논리를 재정의합니다.

첫 번째 작업을 수행하려면 로그인 컨트롤을 템플릿으로 변환하고 필요한 웹 컨트롤을 추가해야 합니다. 두 번째 작업에서는 컨트롤의 이벤트에 대한 이벤트 처리기를 만들어 로그인 컨트롤의Authenticate 인증 논리를 대체할 수 있습니다.

사용자에게 사용자 이름, 암호 및 전자 메일 주소를 묻는 메시지를 표시하고 제공된 전자 메일 주소가 파일의 전자 메일 주소와 일치하는 경우에만 사용자를 인증하도록 로그인 컨트롤을 업데이트해 보겠습니다. 먼저 로그인 컨트롤의 인터페이스를 템플릿으로 변환해야 합니다. 로그인 컨트롤의 스마트 태그에서 템플릿으로 변환 옵션을 선택합니다.

로그인 컨트롤을 템플릿으로 변환

그림 6: 로그인 컨트롤을 템플릿으로 변환(전체 크기 이미지를 보려면 클릭)

참고

로그인 컨트롤을 템플릿 이전 버전으로 되돌리기 컨트롤의 스마트 태그에서 다시 설정 링크를 클릭합니다.

로그인 컨트롤을 템플릿으로 변환하면 HTML 요소와 사용자 인터페이스를 정의하는 웹 컨트롤이 있는 컨트롤의 선언적 태그에 가 추가 LayoutTemplate 됩니다. 그림 7에서 알 수 있듯이 컨트롤을 템플릿으로 변환하면 템플릿을 사용할 때 이러한 속성 값이 무시되므로 , CreateUserUrl등과 같은 TitleText여러 속성이 속성 창 제거됩니다.

로그인 컨트롤을 템플릿으로 변환할 때 사용할 수 있는 속성 수가 줄어듭니다.

그림 7: 로그인 컨트롤을 템플릿으로 변환할 때 사용할 수 있는 속성이 더 적습니다(전체 크기 이미지를 보려면 클릭).

의 HTML 태그 LayoutTemplate 는 필요에 따라 수정될 수 있습니다. 마찬가지로 새 웹 컨트롤을 템플릿에 자유롭게 추가할 수 있습니다. 그러나 로그인 컨트롤의 핵심 웹 컨트롤은 템플릿에 남아 할당된 ID 값을 유지하는 것이 중요합니다. 특히 또는 Password TextBoxes, CheckBox, 단추, RememberMeLoginButton 레이블 또는 컨트롤을 FailureText 제거하거나 RequiredFieldValidator 이름을 바꾸 UserName 지 마세요.

방문자의 이메일 주소를 수집하려면 서식 파일에 TextBox를 추가해야 합니다. TextBox가 포함된 Password 테이블 행(<tr>)과 다음에 기억 확인란을 포함하는 테이블 행 사이에 다음 선언적 태그를 추가합니다.

<tr>
 <td align="right">
 <asp:Label ID="EmailLabel" runat="server" AssociatedControlID="Email">Email:</asp:Label>
 </td>
 <td>
 <asp:TextBox ID="Email" runat="server"></asp:TextBox>
 <asp:RequiredFieldValidator ID="EmailRequired" runat="server" 
 ControlToValidate="Email" ErrorMessage="Email is required." 
 ToolTip="Email is required." ValidationGroup="myLogin">*</asp:RequiredFieldValidator>
 </td>
</tr>

TextBox를 추가한 Email 후 브라우저를 통해 페이지를 방문합니다. 그림 8에서 볼 수 있듯이 로그인 컨트롤의 사용자 인터페이스에는 이제 세 번째 텍스트 상자가 포함됩니다.

이제 로그인 컨트롤에 사용자의 Email 주소에 대한 텍스트 상자가 포함됩니다.

그림 8: 이제 로그인 컨트롤에 사용자의 Email 주소에 대한 텍스트 상자가 포함되어 있습니다(전체 크기 이미지를 보려면 클릭).

이 시점에서 로그인 컨트롤은 제공된 자격 증명의 유효성을 Membership.ValidateUser 검사하기 위해 메서드를 계속 사용하고 있습니다. 이에 따라 TextBox에 Email 입력된 값은 사용자가 로그인할 수 있는지 여부에 영향을 주지 않습니다. 3단계에서는 사용자 이름과 암호가 유효하고 제공된 이메일 주소가 파일의 이메일 주소와 일치하는 경우에만 자격 증명이 유효한 것으로 간주되도록 로그인 컨트롤의 인증 논리를 재정의하는 방법을 살펴봅니다.

3단계: 로그인 컨트롤의 인증 논리 수정

방문자가 자격 증명을 제공하고 로그인 단추를 클릭하면 포스트백이 계속되고 로그인 컨트롤이 인증 워크플로를 통해 진행됩니다. 워크플로는 이벤트를 발생시켜 시작합니다LoggingIn. 이 이벤트와 연결된 모든 이벤트 처리기는 속성을 로 설정 e.Cancel 하여 로그인 작업을 취소할 true수 있습니다.

로그인 작업이 취소되지 않으면 워크플로가 이벤트를 발생Authenticate시켜 진행됩니다. 이벤트에 대한 Authenticate 이벤트 처리기가 있는 경우 제공된 자격 증명이 유효한지 여부를 결정해야 합니다. 이벤트 처리기가 지정되지 않은 경우 로그인 컨트롤은 메서드를 Membership.ValidateUser 사용하여 자격 증명의 유효성을 확인합니다.

제공된 자격 증명이 유효한 경우 양식 인증 티켓이 만들어 LoggedIn 지고 이벤트가 발생하고 사용자가 적절한 페이지로 리디렉션됩니다. 그러나 자격 증명이 유효하지 않은 LoginError 것으로 간주되면 이벤트가 발생하고 사용자에게 자격 증명이 유효하지 않음을 알리는 메시지가 표시됩니다. 기본적으로 실패 시 로그인 컨트롤은 FailureText 레이블 컨트롤의 Text 속성을 오류 메시지로 설정하기만 하면 됩니다( 로그인 시도가 성공하지 못했습니다. 다시 시도하세요.) 그러나 로그인 컨트롤의 FailureAction 속성이 로 설정된 RedirectToLoginPage경우 로그인 컨트롤은 querystring 매개 변수 loginfailure=1 를 추가하는 로그인 페이지에 을 발급 Response.Redirect 합니다(이로 인해 로그인 컨트롤에 실패 메시지가 표시됨).

그림 9는 인증 워크플로의 흐름도를 제공합니다.

로그인 컨트롤의 인증 워크플로

그림 9: 로그인 컨트롤의 인증 워크플로(전체 크기 이미지를 보려면 클릭)

참고

의 페이지 옵션을 언제 사용할 FailureActionRedirectToLogin 지 궁금하다면 다음 시나리오를 고려하세요. 현재 Site.master master 페이지에는 현재 익명 사용자가 방문할 때 왼쪽 열에 표시되는 Hello라는 텍스트가 있지만 해당 텍스트를 로그인 컨트롤로 바꾸고 싶다고 상상해 보세요. 이렇게 하면 익명 사용자가 로그인 페이지를 직접 방문하도록 요구하는 대신 사이트의 모든 페이지에서 로그인할 수 있습니다. 그러나 사용자가 master 페이지에서 렌더링한 로그인 컨트롤을 통해 로그인할 수 없는 경우 해당 페이지에 새 계정을 만들거나 분실한 암호를 검색하는 링크와 같은 추가 지침, 링크 및 기타 도움말이 포함될 수 있으므로 로그인 페이지(Login.aspx)로 리디렉션하는 것이 합리적일 수 master.

Authenticate이벤트 처리기 만들기

사용자 지정 인증 논리를 연결하려면 로그인 컨트롤의 Authenticate 이벤트에 대한 이벤트 처리기를 만들어야 합니다. 이벤트에 대한 Authenticate 이벤트 처리기를 만들면 다음 이벤트 처리기 정의가 생성됩니다.

protected void myLogin_Authenticate(object sender, AuthenticateEventArgs e)
{
}

Authenticate 수 있듯이 이벤트 처리기는 형식 AuthenticateEventArgs 의 개체를 두 번째 입력 매개 변수로 전달합니다. 클래스에는 AuthenticateEventArgs 제공된 자격 증명이 유효한지 여부를 지정하는 데 사용되는 라는 Authenticated 부울 속성이 포함되어 있습니다. 그런 다음, 제공된 자격 증명이 유효한지 여부를 결정하는 코드를 여기에 작성하고 그에 따라 속성을 설정하는 e.Authenticate 것입니다.

제공된 자격 증명 확인 및 유효성 검사

로그인 컨트롤 및 UserNamePassword 속성을 사용하여 사용자가 입력한 사용자 이름 및 암호 자격 증명을 확인합니다. 추가 웹 컨트롤에 입력한 값(예: Email 이전 단계에서 추가한 TextBox)을 확인하려면 (""controlID)을 사용하여 LoginControlID.FindControl속성이 ID 와 같은 템플릿의 웹 컨트롤에 대한 프로그래밍 방식 참조를 controlID가져옵니다. 예를 들어 TextBox에 대한 참조를 Email 얻으려면 다음 코드를 사용합니다.

TextBox EmailTextBox = myLogin.FindControl("Email") as TextBox;

사용자의 자격 증명의 유효성을 검사하려면 다음 두 가지 작업을 수행해야 합니다.

  1. 제공된 사용자 이름 및 암호가 유효한지 확인합니다.
  2. 입력한 전자 메일 주소가 로그인을 시도하는 사용자의 파일의 전자 메일 주소와 일치하는지 확인합니다.

첫 번째 검사 수행하려면 1단계에서 확인한 것처럼 메서드를 Membership.ValidateUser 사용할 수 있습니다. 두 번째 검사 사용자의 전자 메일 주소를 확인하여 TextBox 컨트롤에 입력한 전자 메일 주소와 비교할 수 있도록 해야 합니다. 특정 사용자에 대한 정보를 얻으려면 클래스의 GetUser 메서드Membership 사용합니다.

메서드에는 GetUser 여러 오버로드가 있습니다. 매개 변수를 전달하지 않고 사용하는 경우 현재 로그인한 사용자에 대한 정보를 반환합니다. 특정 사용자에 대한 정보를 얻으려면 사용자 이름을 전달하도록 호출 GetUser 합니다. 어느 쪽이든 , GetUser , , 등과 같은 IsApprovedUserNameIsOnlineEmail속성이 있는 개체를 반환MembershipUser합니다.

다음 코드는 이러한 두 검사를 구현합니다. 둘 다 통과 e.Authenticate 하면 가 로 true설정되고, 그렇지 않으면 가 할당됩니다 false.

protected void myLogin_Authenticate(object sender, AuthenticateEventArgs e)
{
    // Get the email address entered
    TextBox EmailTextBox = myLogin.FindControl("Email") as TextBox;
    string email = EmailTextBox.Text.Trim();

    // Verify that the username/password pair is valid
    if (Membership.ValidateUser(myLogin.UserName, myLogin.Password))
    {
        // Username/password are valid, check email
        MembershipUser usrInfo = Membership.GetUser(myLogin.UserName);
        if (usrInfo != null && string.Compare(usrInfo.Email, email, true) == 0)
        {
            // Email matches, the credentials are valid
            e.Authenticated = true;
        }
        else
        {
            // Email address is invalid...
            e.Authenticated = false;
        }
    }
    else
    {
        // Username/password are not valid...
        e.Authenticated = false;
    }
}

이 코드를 사용하면 올바른 사용자 이름, 암호 및 전자 메일 주소를 입력하여 유효한 사용자로 로그인하려고 시도합니다. 다시 시도하지만 이번에는 의도적으로 잘못된 전자 메일 주소를 사용합니다(그림 10 참조). 마지막으로 존재하지 않는 사용자 이름을 사용하여 세 번째로 시도합니다. 첫 번째 경우 사이트에 성공적으로 로그온해야 하지만 마지막 두 경우 로그인 컨트롤의 잘못된 자격 증명 메시지가 표시됩니다.

잘못된 Email 주소를 제공할 때 Tito에서 로그인할 수 없음

그림 10: 잘못된 Email 주소를 제공할 때 Tito에서 로그인할 수 없음(전체 크기 이미지를 보려면 클릭)

참고

1 Membership.ValidateUser 단계의 멤버 자격 프레임워크가 잘못된 로그인 시도를 처리하는 방법 섹션에서 설명한 것처럼 메서드가 호출되고 잘못된 자격 증명을 전달하면 잘못된 로그인 시도를 추적하고 지정된 기간 내에 잘못된 시도의 특정 임계값을 초과하는 경우 사용자를 잠급니다. 사용자 지정 인증 논리가 메서드를 호출 ValidateUser 하므로 유효한 사용자 이름에 대한 잘못된 암호는 잘못된 로그인 시도 카운터를 증가시키지만 사용자 이름과 암호가 유효하지만 이메일 주소가 잘못된 경우 이 카운터는 증가하지 않습니다. 해커가 사용자 이름과 암호를 알 가능성은 낮지만 무차별 암호 대입 기술을 사용하여 사용자의 이메일 주소를 결정해야 하기 때문에 이 동작이 적합할 수 있습니다.

4단계: 로그인 컨트롤의 잘못된 자격 증명 메시지 개선

사용자가 잘못된 자격 증명으로 로그온하려고 하면 로그인 시도가 실패했음을 설명하는 메시지가 로그인 컨트롤에 표시됩니다. 특히 컨트롤은 속성FailureText에 지정된 메시지를 표시합니다. 기본값은 로그인 시도가 성공하지 못했습니다. 다시 시도하세요.

사용자의 자격 증명이 잘못되었을 수 있는 여러 가지 이유가 있습니다.

  • 사용자 이름이 없을 수 있습니다.
  • 사용자 이름이 있지만 암호가 잘못되었습니다.
  • 사용자 이름과 암호가 유효하지만 사용자는 아직 승인되지 않았습니다.
  • 사용자 이름과 암호는 유효하지만 사용자가 잠겨 있습니다(지정된 시간 프레임 내에서 잘못된 로그인 시도 횟수를 초과했기 때문일 수 있습니다).

또한 사용자 지정 인증 논리를 사용하는 경우 다른 이유가 있을 수 있습니다. 예를 들어 3단계에서 작성한 코드를 사용하면 사용자 이름과 암호가 유효할 수 있지만 전자 메일 주소가 올바르지 않을 수 있습니다.

자격 증명이 잘못된 이유에 관계없이 로그인 컨트롤에 동일한 오류 메시지가 표시됩니다. 이러한 피드백 부족은 계정이 아직 승인되지 않았거나 잠긴 사용자에게 혼란스러울 수 있습니다. 하지만 약간의 작업으로 로그인 컨트롤에 더 적절한 메시지가 표시되도록 할 수 있습니다.

사용자가 잘못된 자격 증명으로 로그인을 시도할 때마다 로그인 컨트롤이 이벤트를 LoginError 발생합니다. 계속 진행하여 이 이벤트에 대한 이벤트 처리기를 만들고 다음 코드를 추가합니다.

protected void myLogin_LoginError(object sender, EventArgs e)
{
    // Determine why the user could not login...
    myLogin.FailureText = "Your login attempt was not successful. Please try again.";

    // Does there exist a User account for this user?
    MembershipUser usrInfo = Membership.GetUser(myLogin.UserName);
    if (usrInfo != null)
    {
        // Is this user locked out?
        if (usrInfo.IsLockedOut)
        {
            myLogin.FailureText = "Your account has been locked out because of too many invalid login attempts. Please contact the administrator to have your account unlocked.";
        }
        else if (!usrInfo.IsApproved)
        {
            myLogin.FailureText = "Your account has not yet been approved. You cannot login until an administrator has approved your account.";
        }
    }
}

위의 코드는 로그인 컨트롤의 FailureText 속성을 기본값(로그인 시도가 실패)으로 설정하여 시작합니다. 다시 시도하세요.) 그런 다음, 제공된 사용자 이름이 기존 사용자 계정에 매핑되는지 확인합니다. 이 경우 결과 MembershipUser 개체 및 IsLockedOutIsApproved 속성을 참조하여 계정이 잠겼는지 또는 아직 승인되지 않은지 확인합니다. 두 경우 모두 속성이 FailureText 해당 값으로 업데이트됩니다.

이 코드를 테스트하려면 의도적으로 기존 사용자로 로그인하려고 하지만 잘못된 암호를 사용합니다. 10분 내에 5회 연속으로 이 작업을 수행하면 계정이 잠깁니다. 그림 11에서 보여 주듯이 후속 로그인 시도는 항상 실패하지만(올바른 암호를 사용하더라도) 잘못된 로그인 시도가 너무 많기 때문에 계정이 잠겼습니다. 계정 잠금 해제 메시지가 있으려면 관리자에게 문의하세요.

Tito가 너무 많은 잘못된 로그인 시도를 수행했으며 잠겼습니다.

그림 11: Tito가 잘못된 로그인 시도를 너무 많이 수행하고 잠겼습니다(전체 크기 이미지를 보려면 클릭).

요약

이 자습서 이전에 로그인 페이지에서는 하드 코딩된 사용자 이름/암호 쌍 목록에 대해 제공된 자격 증명의 유효성을 검사했습니다. 이 자습서에서는 멤버 자격 프레임워크에 대해 자격 증명의 유효성을 검사하도록 페이지를 업데이트했습니다. 1단계에서는 메서드를 프로그래밍 방식으로 사용하는 Membership.ValidateUser 방법을 살펴보았습니다. 2단계에서는 수동으로 만든 사용자 인터페이스 및 코드를 로그인 컨트롤로 대체했습니다.

로그인 컨트롤은 표준 로그인 사용자 인터페이스를 렌더링하고 멤버 자격 프레임워크에 대해 사용자의 자격 증명의 유효성을 자동으로 검사합니다. 또한 유효한 자격 증명이 있는 경우 로그인 컨트롤은 양식 인증을 통해 사용자를 로그인합니다. 즉, 로그인 컨트롤을 페이지로 끌어 추가 선언적 태그 또는 코드가 필요하지 않은 상태로 완벽하게 작동하는 로그인 사용자 환경을 사용할 수 있습니다. 또한 로그인 컨트롤은 사용자 지정이 가능하므로 렌더링된 사용자 인터페이스와 인증 논리를 모두 세부적으로 제어할 수 있습니다.

이 시점에서 웹 사이트 방문자는 새 사용자 계정을 만들고 사이트에 로그인할 수 있지만 인증된 사용자를 기반으로 페이지에 대한 액세스를 제한하는 것을 아직 검토하지 않았습니다. 현재 인증되거나 익명인 모든 사용자는 사이트의 모든 페이지를 볼 수 있습니다. 사용자 단위로 사이트의 페이지에 대한 액세스를 제어하는 기능과 함께 해당 기능이 사용자에 따라 달라지는 특정 페이지가 있을 수 있습니다. 다음 자습서에서는 로그인한 사용자를 기반으로 액세스 및 페이지 내 기능을 제한하는 방법을 알아봅니다.

행복한 프로그래밍!

추가 정보

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

저자 정보

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

특별 감사

이 자습서 시리즈는 많은 유용한 검토자가 검토했습니다. 이 자습서의 수석 검토자는 테레사 머피와 마이클 올리버로였습니다. 예정된 MSDN 문서를 검토하시겠습니까? 그렇다면 에 줄을 놓습니다 mitchell@4GuysFromRolla.com.