비어 있는 또는 기존 Web Forms 프로젝트에 ASP.NET Identity 추가

이 자습서에서는 ASP.NET 애플리케이션에 ASP.NET ID (ASP.NET 새 멤버 자격 시스템)를 추가하는 방법을 보여 줍니다.

Visual Studio 2017 RTM에서 개별 계정으로 새 Web Forms 또는 MVC 프로젝트를 만들 때 Visual Studio는 필요한 모든 패키지를 설치하고 필요한 모든 클래스를 추가합니다. 이 자습서에서는 기존 Web Forms 프로젝트 또는 새 빈 프로젝트에 ASP.NET ID 지원을 추가하는 단계를 보여 줍니다. 설치해야 하는 모든 NuGet 패키지와 추가해야 하는 클래스를 간략하게 설명합니다. 사용자 관리 및 인증을 위한 모든 기본 진입점 API를 강조 표시하면서 새 사용자를 등록하고 로그인하기 위한 샘플 Web Forms 살펴보겠습니다. 이 샘플에서는 Entity Framework를 기반으로 하는 SQL 데이터 스토리지에 대한 ASP.NET ID 기본 구현을 사용합니다. 이 자습서에서는 SQL 데이터베이스에 LocalDB를 사용합니다.

ASP.NET ID 시작

  1. 먼저 Visual Studio 2017을 설치하고 실행합니다.

  2. 시작 페이지에서 새 프로젝트를 선택하거나 메뉴를 사용하여 파일을 선택한 다음 새 프로젝트를 선택할 수 있습니다.

  3. 왼쪽 창에서 Visual C#을 확장한 다음 을 선택한 다음 웹 애플리케이션(.Net Framework)을 ASP.NET. 프로젝트의 이름을 "WebFormsIdentity"로 지정하고 확인을 선택합니다.

    새 프로젝트 만들기를 표시하는 이미지

  4. 새 ASP.NET 프로젝트 대화 상자에서 템플릿을 선택합니다.

    새 A SP dot N E T 프로젝트 대화 상자 창

    인증 변경 단추가 비활성화되어 있으며 이 템플릿에는 인증 지원이 제공되지 않습니다. Web Forms, MVC 및 Web API 템플릿을 사용하면 인증 방법을 선택할 수 있습니다.

앱에 ID 패키지 추가

솔루션 탐색기 프로젝트를 마우스 오른쪽 단추로 클릭하고 NuGet 패키지 관리를 선택합니다. Microsoft.AspNet.Identity.EntityFramework 패키지를 검색하여 설치합니다.

Nu Get 패키지 관리에 액세스하는 방법을 보여 주는 이미지

이 패키지는 EntityFrameworkMicrosoft ASP.NET Identity Core와 같은 종속성 패키지를 설치합니다.

사용자를 등록하는 웹 양식 추가

  1. 솔루션 탐색기 프로젝트를 마우스 오른쪽 단추로 클릭하고 추가를 선택한 다음 웹 양식을 선택합니다.

    등록된 사용자에게 웹 양식을 추가하는 방법을 보여 주는 이미지

  2. 항목에 대한 이름 지정 대화 상자에서 새 웹 양식의 이름을 Register로 지정한 다음 확인을 선택합니다.

  3. 생성된 Register.aspx 파일의 태그를 아래 코드로 바꿉니다. 코드 변경 내용은 강조 표시되어 있습니다.

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Register.aspx.cs" Inherits="WebFormsIdentity.Register" %>
    
    <!DOCTYPE html>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body style="font-family: Arial, Helvetica, sans-serif; font-size: small">
        <form id="form1" runat="server">
        <div>
            <h4 style="font-size: medium">Register a new user</h4>
            <hr />
            <p>
                <asp:Literal runat="server" ID="StatusMessage" />
            </p>                
            <div style="margin-bottom:10px">
                <asp:Label runat="server" AssociatedControlID="UserName">User name</asp:Label>
                <div>
                    <asp:TextBox runat="server" ID="UserName" />                
                </div>
            </div>
            <div style="margin-bottom:10px">
                <asp:Label runat="server" AssociatedControlID="Password">Password</asp:Label>
                <div>
                    <asp:TextBox runat="server" ID="Password" TextMode="Password" />                
                </div>
            </div>
            <div style="margin-bottom:10px">
                <asp:Label runat="server" AssociatedControlID="ConfirmPassword">Confirm password</asp:Label>
                <div>
                    <asp:TextBox runat="server" ID="ConfirmPassword" TextMode="Password" />                
                </div>
            </div>
            <div>
                <div>
                    <asp:Button runat="server" OnClick="CreateUser_Click" Text="Register" />
                </div>
            </div>
        </div>
        </form>
    </body>
    </html>
    

    참고

    새 ASP.NET Web Forms 프로젝트를 만들 때 만들어지는 Register.aspx 파일의 간소화된 버전일 뿐입니다. 위의 태그는 양식 필드와 단추를 추가하여 새 사용자를 등록합니다.

  4. Register.aspx.cs 파일을 열고 파일의 내용을 다음 코드로 바꿉니다.

    using Microsoft.AspNet.Identity;
    using Microsoft.AspNet.Identity.EntityFramework;
    using System;
    using System.Linq;
    
    namespace WebFormsIdentity
    {
       public partial class Register : System.Web.UI.Page
       {
          protected void CreateUser_Click(object sender, EventArgs e)
          {
             // Default UserStore constructor uses the default connection string named: DefaultConnection
             var userStore = new UserStore<IdentityUser>();
             var manager = new UserManager<IdentityUser>(userStore);
    
             var user = new IdentityUser() { UserName = UserName.Text };
             IdentityResult result = manager.Create(user, Password.Text);
    
             if (result.Succeeded)
             {
                StatusMessage.Text = string.Format("User {0} was created successfully!", user.UserName);
             }
             else
             {
                StatusMessage.Text = result.Errors.FirstOrDefault();
             }
          }
       }
    }
    

    참고

    1. 위의 코드는 새 ASP.NET Web Forms 프로젝트를 만들 때 만들어지는 Register.aspx.cs 파일의 간소화된 버전입니다.
    2. IdentityUser 클래스는 IUser 인터페이스의 기본 EntityFramework 구현입니다. IUser 인터페이스는 ASP.NET Identity Core 사용자에 대한 최소한의 인터페이스입니다.
    3. UserStore 클래스는 사용자 저장소의 기본 EntityFramework 구현입니다. 이 클래스는 ASP.NET Identity Core의 최소 인터페이스인 IUserStore, IUserLoginStore, IUserClaimStoreIUserRoleStore를 구현합니다.
    4. UserManager 클래스는 UserStore에 대한 변경 내용을 자동으로 저장하는 사용자 관련 API를 노출합니다.
    5. IdentityResult 클래스는 ID 작업의 결과를 나타냅니다.
  5. 솔루션 탐색기 프로젝트를 마우스 오른쪽 단추로 클릭하고 추가, ASP.NET 폴더 추가를 선택한 다음, App_Data.

    앱 데이터를 추가하는 방법 그림

  6. Web.config 파일을 열고 사용자 정보를 저장하는 데 사용할 데이터베이스에 대한 연결 문자열 항목을 추가합니다. 데이터베이스는 런타임에 Identity 엔터티에 대한 EntityFramework에 의해 만들어집니다. 연결 문자열은 새 Web Forms 프로젝트를 만들 때 만든 문자열과 비슷합니다. 강조 표시된 코드는 추가해야 하는 태그를 보여 줍니다.

    <?xml version="1.0" encoding="utf-8"?>
    <!--
      For more information on how to configure your ASP.NET application, please visit
      https://go.microsoft.com/fwlink/?LinkId=169433
      -->
    <configuration>
      <configSections>
        <!-- For more information on Entity Framework configuration, visit https://go.microsoft.com/fwlink/?LinkID=237468 -->
        <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
      </configSections>
       <connectionStrings>
          <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\WebFormsIdentity.mdf;Initial Catalog=WebFormsIdentity;Integrated Security=True"
                providerName="System.Data.SqlClient" />
       </connectionStrings>
      <system.web>
        <compilation debug="true" targetFramework="4.5" />
        <httpRuntime targetFramework="4.5" />
      </system.web>
      <entityFramework>
        <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
          <parameters>
            <parameter value="v11.0" />
          </parameters>
        </defaultConnectionFactory>
        <providers>
          <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
        </providers>
      </entityFramework>
    </configuration>
    

    참고

    Visual Studio 2015 이상의 경우 을 연결 문자열에서 로 (localdb)\MSSQLLocalDB 대체 (localdb)\v11.0 합니다.

  7. 프로젝트에서 Register.aspx 파일을 마우스 오른쪽 단추 로 클릭하고 시작 페이지로 설정을 선택합니다. Ctrl+F5를 눌러 웹 애플리케이션을 빌드 및 실행합니다. 새 사용자 이름 및 암호를 입력한 다음 등록을 선택합니다.

    새 사용자 등록에 성공한 이미지

    참고

    ASP.NET ID는 유효성 검사를 지원하며 이 샘플에서는 Identity Core 패키지에서 제공되는 사용자 및 암호 유효성 검사기의 기본 동작을 확인할 수 있습니다. User(UserValidator)의 기본 유효성 검사기에는 기본값이 로 설정된 속성 AllowOnlyAlphanumericUserNames 이 있습니다 true. 암호(MinimumLengthValidator)의 기본 유효성 검사기는 암호에 6자 이상이 있는지 확인합니다. 이러한 유효성 검사기는 사용자 지정 유효성 검사를 수행하려는 경우 재정의할 수 있는 의 속성 UserManager 입니다.

Entity Framework에서 생성된 LocalDb ID 데이터베이스 및 테이블 확인

  1. 보기 메뉴에서 서버 Explorer 선택합니다.

    서버 탐색기에 액세스하는 방법의 이미지

  2. DefaultConnection(WebFormsIdentity)을 확장하고 테이블을 확장하고 AspNetUsers를 마우스 오른쪽 단추로 클릭한 다음 테이블 데이터 표시를 선택합니다.

    테이블 데이터 표시에 액세스하는 방법의 이미지
    등록된 사용자의 테이블 데이터를 표시하는 이미지

OWIN 인증을 위한 애플리케이션 구성

이 시점에서 사용자를 만들기 위한 지원만 추가했습니다. 이제 사용자를 로그인하기 위해 인증을 추가하는 방법을 보여 줍니다. ASP.NET ID는 양식 인증에 Microsoft OWIN 인증 미들웨어를 사용합니다. OWIN 쿠키 인증은 OWIN 또는 IIS에서 호스트되는 프레임워크에서 사용할 수 있는 쿠키 및 클레임 기반 인증 메커니즘입니다. 이 모델을 사용하면 ASP.NET MVC 및 Web Forms 비롯한 여러 프레임워크에서 동일한 인증 패키지를 사용할 수 있습니다. 프로젝트 Katana에 대한 자세한 내용과 호스트에 구애받지 않은 상태에서 미들웨어를 실행하는 방법에 대한 자세한 내용은 Katana 프로젝트 시작 참조하세요.

애플리케이션에 인증 패키지 설치

  1. 솔루션 탐색기 프로젝트를 마우스 오른쪽 단추로 클릭하고 NuGet 패키지 관리를 선택합니다. Microsoft.AspNet.Identity.Owin 패키지를 검색하여 설치합니다.

    Nu Get 패키지 관리자 이미지

  2. Microsoft.Owin.Host.SystemWeb 패키지를 검색하여 설치합니다.

    참고

    Microsoft.Aspnet.Identity.Owin 패키지에는 ASP.NET Identity Core 패키지에서 사용할 OWIN 인증 미들웨어를 관리하고 구성하는 OWIN 확장 클래스 집합이 포함되어 있습니다. Microsoft.Owin.Host.SystemWeb 패키지에는 OWIN 기반 애플리케이션이 ASP.NET 요청 파이프라인을 사용하여 IIS에서 실행할 수 있는 OWIN 서버가 포함되어 있습니다. 자세한 내용은 IIS 통합 파이프라인의 OWIN 미들웨어를 참조하세요.

OWIN 시작 및 인증 구성 클래스 추가

  1. 솔루션 탐색기 프로젝트를 마우스 오른쪽 단추로 클릭하고 추가를 선택한 다음 새 항목 추가를 선택합니다. 검색 텍스트 상자 대화 상자에서 "owin"을 입력합니다. 클래스 이름을 "Startup"으로 지정하고 추가를 선택합니다.

    새 항목 추가 창 이미지

  2. Startup.cs 파일에서 아래에 표시된 강조 표시된 코드를 추가하여 OWIN 쿠키 인증을 구성합니다.

    using Microsoft.AspNet.Identity;
    using Microsoft.Owin;
    using Microsoft.Owin.Security.Cookies;
    using Owin;
    
    [assembly: OwinStartup(typeof(WebFormsIdentity.Startup))]
    
    namespace WebFormsIdentity
    {
       public class Startup
       {
          public void Configuration(IAppBuilder app)
          {
             // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=316888
             app.UseCookieAuthentication(new CookieAuthenticationOptions
             {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath = new PathString("/Login")
             });
          }
       }
    }
    

    참고

    이 클래스에는 OwinStartup OWIN 시작 클래스를 지정하기 위한 특성이 포함되어 있습니다. 모든 OWIN 애플리케이션에는 애플리케이션 파이프라인에 대한 구성 요소를 지정하는 시작 클래스가 있습니다. 이 모델에 대한 자세한 내용은 OWIN 시작 클래스 검색 을 참조하세요.

사용자 등록 및 로그인을 위한 웹 양식 추가

  1. Register.aspx.cs 파일을 열고 등록이 성공하면 사용자에게 로그인하는 다음 코드를 추가합니다.

    using Microsoft.AspNet.Identity;
    using Microsoft.AspNet.Identity.EntityFramework;
    using Microsoft.Owin.Security;
    using System;
    using System.Linq;
    using System.Web;
    
    namespace WebFormsIdentity
    {
       public partial class Register : System.Web.UI.Page
       {
          protected void CreateUser_Click(object sender, EventArgs e)
          {
             // Default UserStore constructor uses the default connection string named: DefaultConnection
             var userStore = new UserStore<IdentityUser>();
             var manager = new UserManager<IdentityUser>(userStore);
             var user = new IdentityUser() { UserName = UserName.Text };
    
             IdentityResult result = manager.Create(user, Password.Text);
    
             if (result.Succeeded)
             {
                var authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
                var userIdentity = manager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie);
                authenticationManager.SignIn(new AuthenticationProperties() { }, userIdentity);
                Response.Redirect("~/Login.aspx");
             }
             else
             {
                StatusMessage.Text = result.Errors.FirstOrDefault();
             }
          }
       }
    }
    

    참고

    • ASP.NET ID 및 OWIN 쿠키 인증은 클레임 기반 시스템이므로 프레임워크에서는 앱 개발자가 사용자에 대한 ClaimsIdentity 를 생성해야 합니다. ClaimsIdentity에는 사용자가 속한 역할과 같은 사용자의 모든 클레임에 대한 정보가 있습니다. 이 단계에서 사용자에 대한 클레임을 더 추가할 수도 있습니다.
    • OWIN에서 AuthenticationManager를 사용하고 위에 표시된 대로 ClaimsIdentity를 호출 SignIn 하고 전달하여 사용자를 로그인할 수 있습니다. 이 코드는 사용자를 로그인하고 쿠키도 생성합니다. 이 호출은 FormsAuthentication 모듈에서 사용하는 FormAuthentication.SetAuthCookie 와 유사 합니다 .
  2. 솔루션 탐색기 프로젝트를 마우스 오른쪽 단추로 클릭하고 추가를 선택한 다음 웹 양식을 선택합니다. 웹 양식의 이름을 로그인으로 지정합니다.

    새 웹 양식을 추가하는 이미지

  3. Login.aspx 파일의 내용을 다음 코드로 바꿉니다.

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Login.aspx.cs" Inherits="WebFormsIdentity.Login" %>
    
    <!DOCTYPE html>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
       <title></title>
    </head>
    <body style="font-family: Arial, Helvetica, sans-serif; font-size: small">
       <form id="form1" runat="server">
          <div>
             <h4 style="font-size: medium">Log In</h4>
             <hr />
             <asp:PlaceHolder runat="server" ID="LoginStatus" Visible="false">
                <p>
                   <asp:Literal runat="server" ID="StatusText" />
                </p>
             </asp:PlaceHolder>
             <asp:PlaceHolder runat="server" ID="LoginForm" Visible="false">
                <div style="margin-bottom: 10px">
                   <asp:Label runat="server" AssociatedControlID="UserName">User name</asp:Label>
                   <div>
                      <asp:TextBox runat="server" ID="UserName" />
                   </div>
                </div>
                <div style="margin-bottom: 10px">
                   <asp:Label runat="server" AssociatedControlID="Password">Password</asp:Label>
                   <div>
                      <asp:TextBox runat="server" ID="Password" TextMode="Password" />
                   </div>
                </div>
                <div style="margin-bottom: 10px">
                   <div>
                      <asp:Button runat="server" OnClick="SignIn" Text="Log in" />
                   </div>
                </div>
             </asp:PlaceHolder>
             <asp:PlaceHolder runat="server" ID="LogoutButton" Visible="false">
                <div>
                   <div>
                      <asp:Button runat="server" OnClick="SignOut" Text="Log out" />
                   </div>
                </div>
             </asp:PlaceHolder>
          </div>
       </form>
    </body>
    </html>
    
  4. Login.aspx.cs 파일의 내용을 다음으로 바꿉니다.

    using Microsoft.AspNet.Identity;
    using Microsoft.AspNet.Identity.EntityFramework;
    using Microsoft.Owin.Security;
    using System;
    using System.Web;
    using System.Web.UI.WebControls;
    
    namespace WebFormsIdentity
    {
       public partial class Login : System.Web.UI.Page
       {
          protected void Page_Load(object sender, EventArgs e)
          {
             if (!IsPostBack)
             {
                if (User.Identity.IsAuthenticated)
                {
                   StatusText.Text = string.Format("Hello {0}!!", User.Identity.GetUserName());
                   LoginStatus.Visible = true;
                   LogoutButton.Visible = true;
                }
                else
                {
                   LoginForm.Visible = true;
                }
             }
          }
    
          protected void SignIn(object sender, EventArgs e)
          {
             var userStore = new UserStore<IdentityUser>();
             var userManager = new UserManager<IdentityUser>(userStore);
             var user = userManager.Find(UserName.Text, Password.Text);
    
             if (user != null)
             {
                var authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
                var userIdentity = userManager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie);
    
                authenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = false }, userIdentity);
                Response.Redirect("~/Login.aspx");
             }
             else
             {
                StatusText.Text = "Invalid username or password.";
                LoginStatus.Visible = true;
             }
          }
    
          protected void SignOut(object sender, EventArgs e)
          {
             var authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
             authenticationManager.SignOut();
             Response.Redirect("~/Login.aspx");
          }
       }
    }
    

    참고

    • 이제 는 Page_Load 현재 사용자의 상태 확인하고 상태 따라 작업을 수행합니다 Context.User.Identity.IsAuthenticated . 로그인한 사용자 이름 표시: Microsoft ASP.NET Identity Framework에 로그인한 사용자에 대해 및 UserId 를 가져올 UserName 수 있는 확장 메서드가 System.Security.Principal.IIdentity에 추가되었습니다. 이러한 확장 메서드는 어셈블리에 Microsoft.AspNet.Identity.Core 정의됩니다. 이러한 확장 메서드는 HttpContext.User.Identity.Name 대체합니다.
    • SignIn 메서드: This 메서드는 이 샘플의 이전 CreateUser_Click 메서드를 대체하고 사용자를 성공적으로 만든 후 사용자에게 로그인합니다.
      Microsoft OWIN Framework에는 에 대한 System.Web.HttpContext 참조 IOwinContext를 가져올 수 있는 확장 메서드가 추가되었습니다. 이러한 확장 메서드는 어셈블리에 Microsoft.Owin.Host.SystemWeb 정의됩니다. 클래스는 OwinContext 현재 요청에서 IAuthenticationManager 사용할 수 있는 인증 미들웨어 기능을 나타내는 속성을 노출합니다. OWIN에서 를 AuthenticationManager 사용하고 를 호출 SignIn 하고 위에 표시된 대로 를 전달하여 사용자를 로그인할 ClaimsIdentity 수 있습니다. ASP.NET ID 및 OWIN 쿠키 인증은 클레임 기반 시스템이므로 프레임워크는 앱에서 사용자에 대한 을 ClaimsIdentity 생성해야 합니다. ClaimsIdentity 에는 사용자의 모든 클레임에 대한 정보(예: 사용자가 속한 역할)가 있습니다. 이 단계에서 사용자에 대한 클레임을 더 추가할 수도 있습니다. 이 코드는 사용자를 로그인하고 쿠키를 생성합니다. 이 호출은 FormsAuthentication 모듈에서 사용하는 FormAuthentication.SetAuthCookie 와 유사 합니다 .
    • SignOut 메서드: OWIN에서 에 대한 참조를 AuthenticationManager 가져오고 를 호출합니다 SignOut. 이는 FormsAuthentication 모듈에서 사용하는 FormsAuthentication.SignOut 메서드와 유사 합니다 .
  5. Ctrl + F5를 눌러 웹 애플리케이션을 빌드하고 실행합니다. 새 사용자 이름 및 암호를 입력한 다음 등록을 선택합니다.

    새 usr 등록 이미지
    참고: 이 시점에서 새 사용자가 만들어지고 로그인됩니다.

  6. 로그아웃 단추를 선택합니다. 로그 형식으로 리디렉션됩니다.

  7. 잘못된 사용자 이름 또는 암호를 입력하고 로그인 단추를 선택합니다. 메서드는 UserManager.Find null을 반환하고 " 잘못된 사용자 이름 또는 암호 "라는 오류 메시지가 표시됩니다.

    잘못된 로그인 시도 이미지