ASP.NET Core 소개 Identity

작성자: Rick Anderson

ASP.NET Core Identity:

  • 는 UI (사용자 인터페이스) 로그인 기능을 지 원하는 API입니다.
  • 사용자, 암호, 프로필 데이터, 역할, 클레임, 토큰, 전자 메일 확인 등을 관리 합니다.

사용자는에 저장 된 로그인 정보를 사용 하 여 계정을 만들거나 Identity 외부 로그인 공급자를 사용할 수 있습니다. 지원 되는 외부 로그인 공급자에는 Facebook, Google, Microsoft 계정 및 Twitter가 포함 됩니다.

모든 사용자의 인증을 전역으로 요구하는 방법에 대한 자세한 내용은 인증된 사용자 요구를 참조하세요.

Identity 소스 코드 는 GitHub에서 사용할 수 있습니다. 스 캐 폴드 Identity 및는 생성 된 파일을 확인 하 여와의 템플릿 상호 작용을 검토 Identity 합니다.

Identity 는 일반적으로 사용자 이름, 암호 및 프로필 데이터를 저장 하기 위해 SQL Server 데이터베이스를 사용 하 여 구성 됩니다. 또는 Azure Table Storage와 같은 또 다른 영구 저장소를 사용할 수 있습니다.

이 항목에서는를 사용 하 여 사용자를 Identity 등록 하 고 로그인 하 고 로그 아웃 하는 방법을 알아봅니다. 참고: 템플릿은 사용자에 대해 사용자 이름 및 전자 메일을 동일 하 게 처리 합니다. 를 사용 하는 앱을 만드는 방법에 대 한 자세한 지침은 Identity 다음 단계를 참조 하세요.

Microsoft id 플랫폼 은 다음과 같습니다.

  • Azure Active Directory (Azure AD) 개발자 플랫폼의 진화
  • 와 관련이 ASP.NET Core Identity 없습니다.

ASP.NET Core Identity는 ASP.NET Core 웹앱에 UI(사용자 인터페이스) 로그인 기능을 추가합니다. 웹 API 및 SPA를 보호하려면 다음 중 하나를 사용합니다.

IdentityServer4는 ASP.NET Core용 OpenID Connect 및 OAuth 2.0 프레임워크입니다. IdentityServer4에서는 다음과 같은 보안 기능을 사용할 수 있습니다.

  • AaaS(Authentication as a Service)
  • 여러 응용 프로그램 유형에 대한 SSO(Single Sign-On/Off)
  • API에 대한 액세스 제어
  • 페더레이션 게이트웨이

자세한 내용은 IdentityServer4 시작을 참조하세요.

샘플 코드 보기 또는 다운로드 (다운로드 방법)

인증을 사용 하 여 웹 앱 만들기

개별 사용자 계정으로 ASP.NET Core 웹 애플리케이션 프로젝트를 만듭니다.

  • 파일 > > 프로젝트 를 선택합니다.
  • 새 ASP.NET Core 웹 애플리케이션 을 선택합니다. 프로젝트 이름을 WebApp1로 지정하여 프로젝트 다운로드와 동일한 네임스페이스를 갖습니다. 확인 을 클릭합니다.
  • ASP.NET Core 웹 애플리케이션을 선택한 다음, 인증 변경을 선택합니다.
  • 개별 사용자 계정을 선택하고 확인을 클릭합니다.

생성된 프로젝트는 ASP.NET Core Identity Razor 를 클래스 라이브러리로 제공합니다. Identity Razor 클래스 라이브러리는 영역이 있는 엔드포인트를 Identity 노출합니다. 예를 들어:

  • /Identity/Account/Login
  • /Identity/Account/Logout
  • /Identity/Account/Manage

마이그레이션 적용

마이그레이션을 적용하여 데이터베이스를 초기화합니다.

PMC(패키지 관리자 콘솔)에서 다음 명령을 실행합니다.

PM> Update-Database

테스트 등록 및 로그인

앱을 실행하고 사용자를 등록합니다. 화면 크기에 따라 탐색 토글 단추를 선택하여 등록로그인 링크를 확인해야 할 수 있습니다.

데이터베이스 보기 Identity

  • 보기 메뉴에서 SQL Server 개체 탐색기 (SSOX)를 선택 합니다.
  • (Localdb) MSSQLLocalDB (SQL Server 13) 로 이동 합니다. Dbo를 마우스 오른쪽 단추로 클릭 합니다. AspNetUsers > 뷰 데이터:

SQL Server 개체 탐색기의 AspNetUsers 테이블에 대 한 상황에 맞는 메뉴

서비스 구성 Identity

서비스는에 추가 됩니다 ConfigureServices . 일반적인 패턴은 모든 Add{Service} 메서드를 호출한 후 모든 services.Configure{Service} 메서드를 호출하는 것입니다.

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
     // options.UseSqlite(
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));
    services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
        .AddEntityFrameworkStores<ApplicationDbContext>();
    services.AddRazorPages();

    services.Configure<IdentityOptions>(options =>
    {
        // Password settings.
        options.Password.RequireDigit = true;
        options.Password.RequireLowercase = true;
        options.Password.RequireNonAlphanumeric = true;
        options.Password.RequireUppercase = true;
        options.Password.RequiredLength = 6;
        options.Password.RequiredUniqueChars = 1;

        // Lockout settings.
        options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
        options.Lockout.MaxFailedAccessAttempts = 5;
        options.Lockout.AllowedForNewUsers = true;

        // User settings.
        options.User.AllowedUserNameCharacters =
        "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
        options.User.RequireUniqueEmail = false;
    });

    services.ConfigureApplicationCookie(options =>
    {
        // Cookie settings
        options.Cookie.HttpOnly = true;
        options.ExpireTimeSpan = TimeSpan.FromMinutes(5);

        options.LoginPath = "/Identity/Account/Login";
        options.AccessDeniedPath = "/Identity/Account/AccessDenied";
        options.SlidingExpiration = true;
    });
}

위의 강조 표시 된 코드는 Identity 기본 옵션 값을 사용 하 여를 구성 합니다. 서비스는 종속성 주입을 통해 앱에서 사용할 수 있게 됩니다.

Identity 는를 호출 하 여 사용할 수 UseAuthentication 있습니다. UseAuthentication 인증 미들웨어 를 요청 파이프라인에 추가 합니다.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}
public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        // options.UseSqlite(
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));
    services.AddDatabaseDeveloperPageExceptionFilter();
    services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
        .AddEntityFrameworkStores<ApplicationDbContext>();
    services.AddRazorPages();

    services.Configure<IdentityOptions>(options =>
    {
        // Password settings.
        options.Password.RequireDigit = true;
        options.Password.RequireLowercase = true;
        options.Password.RequireNonAlphanumeric = true;
        options.Password.RequireUppercase = true;
        options.Password.RequiredLength = 6;
        options.Password.RequiredUniqueChars = 1;

        // Lockout settings.
        options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
        options.Lockout.MaxFailedAccessAttempts = 5;
        options.Lockout.AllowedForNewUsers = true;

        // User settings.
        options.User.AllowedUserNameCharacters =
        "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
        options.User.RequireUniqueEmail = false;
    });

    services.ConfigureApplicationCookie(options =>
    {
        // Cookie settings
        options.Cookie.HttpOnly = true;
        options.ExpireTimeSpan = TimeSpan.FromMinutes(5);

        options.LoginPath = "/Identity/Account/Login";
        options.AccessDeniedPath = "/Identity/Account/AccessDenied";
        options.SlidingExpiration = true;
    });
}

위의 코드는 Identity 기본 옵션 값을 사용 하 여를 구성 합니다. 서비스는 종속성 주입을 통해 앱에서 사용할 수 있게 됩니다.

Identity 는 Useauthentication을 호출 하 여 사용 하도록 설정 됩니다. UseAuthentication 인증 미들웨어 를 요청 파이프라인에 추가 합니다.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseMigrationsEndPoint();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

템플릿에서 생성 된 앱은 권한 부여를 사용 하지 않습니다. app.UseAuthorization 는 앱이 권한 부여를 추가 하는 올바른 순서로 추가 되었는지 확인 하기 위해 포함 됩니다. UseRouting, UseAuthentication , UseAuthorizationUseEndpoints 는 앞의 코드에 표시 된 순서 대로 호출 해야 합니다.

및에 대 한 자세한 내용은 IdentityOptions Startup IdentityOptions응용 프로그램 시작을 참조 하세요.

스 캐 폴드 Register, Login, LogOut 및 RegisterConfirmation

,, Register Login 및 파일을 추가 LogOut RegisterConfirmation 합니다. 이 섹션에 표시 된 코드를 생성 하려면 Razor 권한 부여 지침을 포함 하는 스 캐 폴드 id를 프로젝트에 추가 합니다.

레지스터 검사

사용자가 페이지에서 등록 단추를 클릭하면 Register 작업이 RegisterModel.OnPostAsync 호출됩니다. 사용자는 개체에 대해 CreateAsync에 의해 만들어집니다. _userManager

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
    returnUrl = returnUrl ?? Url.Content("~/");
    ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync())
                                          .ToList();
    if (ModelState.IsValid)
    {
        var user = new IdentityUser { UserName = Input.Email, Email = Input.Email };
        var result = await _userManager.CreateAsync(user, Input.Password);
        if (result.Succeeded)
        {
            _logger.LogInformation("User created a new account with password.");

            var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
            code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
            var callbackUrl = Url.Page(
                "/Account/ConfirmEmail",
                pageHandler: null,
                values: new { area = "Identity", userId = user.Id, code = code },
                protocol: Request.Scheme);

            await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
                $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");

            if (_userManager.Options.SignIn.RequireConfirmedAccount)
            {
                return RedirectToPage("RegisterConfirmation", 
                                      new { email = Input.Email });
            }
            else
            {
                await _signInManager.SignInAsync(user, isPersistent: false);
                return LocalRedirect(returnUrl);
            }
        }
        foreach (var error in result.Errors)
        {
            ModelState.AddModelError(string.Empty, error.Description);
        }
    }

    // If we got this far, something failed, redisplay form
    return Page();
}

기본 계정 확인 사용 안 함

기본 템플릿을 사용 하면 사용자가 Account.RegisterConfirmation 계정 확인을 위해 링크를 선택할 수 있는 위치로 리디렉션됩니다. 기본값은 Account.RegisterConfirmation 테스트에 사용 되며 자동 계정 확인은 프로덕션 앱에서 사용 하지 않도록 설정 해야 합니다.

확인 된 계정을 요구 하 고 등록 시 즉각적인 로그인을 방지 하려면 DisplayConfirmAccountLink = false /Areas/ Identity /Pages/Account/RegisterConfirmation.cshtml.cs 에서를 설정 합니다.

[AllowAnonymous]
public class RegisterConfirmationModel : PageModel
{
    private readonly UserManager<IdentityUser> _userManager;
    private readonly IEmailSender _sender;

    public RegisterConfirmationModel(UserManager<IdentityUser> userManager, IEmailSender sender)
    {
        _userManager = userManager;
        _sender = sender;
    }

    public string Email { get; set; }

    public bool DisplayConfirmAccountLink { get; set; }

    public string EmailConfirmationUrl { get; set; }

    public async Task<IActionResult> OnGetAsync(string email, string returnUrl = null)
    {
        if (email == null)
        {
            return RedirectToPage("/Index");
        }

        var user = await _userManager.FindByEmailAsync(email);
        if (user == null)
        {
            return NotFound($"Unable to load user with email '{email}'.");
        }

        Email = email;
        // Once you add a real email sender, you should remove this code that lets you confirm the account
        DisplayConfirmAccountLink = false;
        if (DisplayConfirmAccountLink)
        {
            var userId = await _userManager.GetUserIdAsync(user);
            var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
            code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
            EmailConfirmationUrl = Url.Page(
                "/Account/ConfirmEmail",
                pageHandler: null,
                values: new { area = "Identity", userId = userId, code = code, returnUrl = returnUrl },
                protocol: Request.Scheme);
        }

        return Page();
    }
}

로그인

로그인 양식은 다음과 같은 경우에 표시됩니다.

  • 로그인 링크가 선택되어 있습니다.
  • 사용자가 액세스 권한이 없거나 시스템에서 인증되지 않은 제한된 페이지에 액세스하려고 합니다.

로그인 페이지의 양식이 제출되면 OnPostAsync 작업이 호출됩니다. PasswordSignInAsync``_signInManager는 개체에서 호출됩니다.

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
    returnUrl = returnUrl ?? Url.Content("~/");

    if (ModelState.IsValid)
    {
        // This doesn't count login failures towards account lockout
        // To enable password failures to trigger account lockout, 
        // set lockoutOnFailure: true
        var result = await _signInManager.PasswordSignInAsync(Input.Email,
                           Input.Password, Input.RememberMe, lockoutOnFailure: true);
        if (result.Succeeded)
        {
            _logger.LogInformation("User logged in.");
            return LocalRedirect(returnUrl);
        }
        if (result.RequiresTwoFactor)
        {
            return RedirectToPage("./LoginWith2fa", new
            {
                ReturnUrl = returnUrl,
                RememberMe = Input.RememberMe
            });
        }
        if (result.IsLockedOut)
        {
            _logger.LogWarning("User account locked out.");
            return RedirectToPage("./Lockout");
        }
        else
        {
            ModelState.AddModelError(string.Empty, "Invalid login attempt.");
            return Page();
        }
    }

    // If we got this far, something failed, redisplay form
    return Page();
}

권한 부여 결정을 내리는 방법에 대한 자세한 내용은 를 ASP.NET Core의 권한 부여 소개 참조하세요.

로그아웃

로그아웃 링크는 LogoutModel.OnPost 작업을 호출합니다.

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;

namespace WebApp1.Areas.Identity.Pages.Account
{
    [AllowAnonymous]
    public class LogoutModel : PageModel
    {
        private readonly SignInManager<IdentityUser> _signInManager;
        private readonly ILogger<LogoutModel> _logger;

        public LogoutModel(SignInManager<IdentityUser> signInManager, ILogger<LogoutModel> logger)
        {
            _signInManager = signInManager;
            _logger = logger;
        }

        public void OnGet()
        {
        }

        public async Task<IActionResult> OnPost(string returnUrl = null)
        {
            await _signInManager.SignOutAsync();
            _logger.LogInformation("User logged out.");
            if (returnUrl != null)
            {
                return LocalRedirect(returnUrl);
            }
            else
            {
                return RedirectToPage();
            }
        }
    }
}

앞의 코드에서 코드는 return RedirectToPage(); 브라우저가 새 요청을 수행하고 사용자의 ID가 업데이트되도록 리디렉션이어야 합니다.

SignOutAsync는 에 저장된 사용자의 클레임을 cookie 지웁니다.

Post는 Pages/Shared/_LoginPartial.cshtml 에 지정됩니다.

@using Microsoft.AspNetCore.Identity
@inject SignInManager<IdentityUser> SignInManager
@inject UserManager<IdentityUser> UserManager

<ul class="navbar-nav">
@if (SignInManager.IsSignedIn(User))
{
    <li class="nav-item">
        <a  class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" 
                                              title="Manage">Hello @User.Identity.Name!</a>
    </li>
    <li class="nav-item">
        <form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" 
                                  asp-route-returnUrl="@Url.Page("/", new { area = "" })" 
                                  method="post" >
            <button  type="submit" class="nav-link btn btn-link text-dark">Logout</button>
        </form>
    </li>
}
else
{
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Register">Register</a>
    </li>
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login">Login</a>
    </li>
}
</ul>

테스트 Identity

기본 웹 프로젝트 템플릿은 홈 페이지에 대한 익명 액세스를 허용합니다. 를 테스트하려면 Identity [Authorize] 를 추가합니다.

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;

namespace WebApp1.Pages
{
    [Authorize]
    public class PrivacyModel : PageModel
    {
        private readonly ILogger<PrivacyModel> _logger;

        public PrivacyModel(ILogger<PrivacyModel> logger)
        {
            _logger = logger;
        }

        public void OnGet()
        {
        }
    }
}

로그인한 경우 로그아웃합니다. 앱을 실행하고 Privacy 링크를 선택합니다. 로그인 페이지로 리디렉션됩니다.

탐험 Identity

자세히 살펴보기 Identity :

Identity 요소도

모든 Identity 종속 NuGet 패키지는 ASP.NET Core 공유 프레임 워크에 포함 되어 있습니다.

의 기본 패키지는 Identity AspNetCore입니다. Identity 이 패키지에는에 대 한 핵심 인터페이스 집합이 포함 되어 ASP.NET Core Identity 있으며,에 포함 되어 Microsoft.AspNetCore.Identity.EntityFrameworkCore 있습니다.

로 마이그레이션 ASP.NET Core Identity

기존 저장소 마이그레이션에 대 한 자세한 내용 및 지침은 Identity 인증 및 Identity 마이그레이션 을 참조 하세요.

암호 강도 설정

최소 암호 요구 사항을 설정 하는 예제는 구성 을 참조 하세요.

AddDefault Identity 및 AddIdentity

AddDefaultIdentity 는 ASP.NET Core 2.1에서 도입 되었습니다. 호출은 AddDefaultIdentity 다음을 호출 하는 것과 비슷합니다.

자세한 내용은 Adddefault Identity source 를 참조 하세요.

정적 자산 게시 방지 Identity

IdentityUI에 대 한 정적 자산 (스타일 시트 및 JavaScript 파일 Identity )을 웹 루트에 게시 하지 않으려면 다음 ResolveStaticWebAssetsInputsDependsOn 속성과 RemoveIdentityAssets 대상을 응용 프로그램의 프로젝트 파일에 추가 합니다.

<PropertyGroup>
  <ResolveStaticWebAssetsInputsDependsOn>RemoveIdentityAssets</ResolveStaticWebAssetsInputsDependsOn>
</PropertyGroup>

<Target Name="RemoveIdentityAssets">
  <ItemGroup>
    <StaticWebAsset Remove="@(StaticWebAsset)" Condition="%(SourceId) == 'Microsoft.AspNetCore.Identity.UI'" />
  </ItemGroup>
</Target>

다음 단계

작성자: Rick Anderson

ASP.NET Core Identity 는 ASP.NET Core 앱에 로그인 기능을 추가 하는 멤버 자격 시스템입니다. 사용자는에 저장 된 로그인 정보를 사용 하 여 계정을 만들거나 Identity 외부 로그인 공급자를 사용할 수 있습니다. 지원되는 외부 로그인 공급자에는 Facebook, Google, Microsoft 계정 및 Twitter가 포함됩니다.

Identity SQL Server 데이터베이스를 사용하여 사용자 이름, 암호 및 프로필 데이터를 저장하도록 구성할 수 있습니다. 또는 다른 영구 저장소(예: Azure Table Storage)를 사용할 수 있습니다.

샘플 코드(다운로드 방법)를 보거나 다운로드합니다.

이 항목에서는 를 사용하여 Identity 사용자를 등록, 로그인 및 로그아웃하는 방법을 알아봅니다. 를 사용하는 앱을 만드는 방법에 대한 자세한 지침은 Identity 이 문서의 끝에 있는 다음 단계 섹션을 참조하세요.

AddDefault Identity 및 추가Identity

AddDefaultIdentity 는 ASP.NET Core 2.1에서 도입되었습니다. 를 AddDefaultIdentity 호출하는 것은 다음을 호출하는 것과 비슷합니다.

자세한 내용은 AddDefault Identity 원본을 참조하세요.

인증을 사용하여 웹앱 만들기

개별 사용자 계정으로 ASP.NET Core 웹 애플리케이션 프로젝트를 만듭니다.

  • 파일 > > 프로젝트 를 선택합니다.
  • 새 ASP.NET Core 웹 애플리케이션 을 선택합니다. 프로젝트 이름을 WebApp1로 지정하여 프로젝트 다운로드와 동일한 네임스페이스를 갖습니다. 확인 을 클릭합니다.
  • ASP.NET Core 웹 애플리케이션을 선택한 다음, 인증 변경을 선택합니다.
  • 개별 사용자 계정을 선택하고 확인을 클릭합니다.

생성된 프로젝트는 ASP.NET Core Identity Razor 를 클래스 라이브러리로 제공합니다. Identity Razor 클래스 라이브러리는 영역이 있는 엔드포인트를 Identity 노출합니다. 예를 들어:

  • /Identity/Account/Login
  • /Identity/Account/Logout
  • /Identity/계정/관리

마이그레이션 적용

마이그레이션을 적용 하 여 데이터베이스를 초기화 합니다.

패키지 관리자 콘솔 (PMC)에서 다음 명령을 실행 합니다.

Update-Database

테스트 등록 및 로그인

앱을 실행 하 고 사용자를 등록 합니다. 화면 크기에 따라, 탐색 토글 단추를 선택 하 여 등록로그인 링크를 확인 해야 할 수도 있습니다.

데이터베이스 보기 Identity

  • 보기 메뉴에서 SQL Server 개체 탐색기 (SSOX)를 선택 합니다.
  • (Localdb) MSSQLLocalDB (SQL Server 13) 로 이동 합니다. Dbo를 마우스 오른쪽 단추로 클릭 합니다. AspNetUsers > 뷰 데이터:

SQL Server 개체 탐색기의 AspNetUsers 테이블에 대 한 상황에 맞는 메뉴

Identity서비스 구성

서비스는에 추가 됩니다 ConfigureServices . 일반적인 패턴은 모든 Add{Service} 메서드를 호출한 후 모든 services.Configure{Service} 메서드를 호출하는 것입니다.

위의 코드는 Identity 기본 옵션 값을 사용 하 여를 구성 합니다. 서비스는 종속성 주입을 통해 앱에서 사용할 수 있게 됩니다.

Identity 는 Useauthentication을 호출 하 여 사용 하도록 설정 됩니다. UseAuthentication 인증 미들웨어 를 요청 파이프라인에 추가 합니다.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseCookiePolicy();

    app.UseAuthentication();

    app.UseMvc();
}

자세한 내용은 Identity 옵션 클래스응용 프로그램 시작을 참조 하세요.

스 캐 폴드 Register, Login 및 LogOut

이 섹션에 표시 된 코드를 생성 하려면 Razor 권한 부여 지침을 포함 하는 스 캐 폴드 id를 프로젝트에 추가 합니다.

Register, Login 및 LogOut 파일을 추가 합니다.

레지스터 검사

사용자가 등록 링크를 클릭하면 작업이 RegisterModel.OnPostAsync 호출됩니다. 사용자는 개체에 대해 CreateAsync에 의해 만들어집니다. _userManager

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
    returnUrl = returnUrl ?? Url.Content("~/");
    if (ModelState.IsValid)
    {
        var user = new IdentityUser { UserName = Input.Email, Email = Input.Email };
        var result = await _userManager.CreateAsync(user, Input.Password);
        if (result.Succeeded)
        {
            _logger.LogInformation("User created a new account with password.");

            var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
            var callbackUrl = Url.Page(
                "/Account/ConfirmEmail",
                pageHandler: null,
                values: new { userId = user.Id, code = code },
                protocol: Request.Scheme);

            await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
                $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");

            await _signInManager.SignInAsync(user, isPersistent: false);
            return LocalRedirect(returnUrl);
        }
        foreach (var error in result.Errors)
        {
            ModelState.AddModelError(string.Empty, error.Description);
        }
    }

    // If we got this far, something failed, redisplay form
    return Page();
}

사용자가 성공적으로 만들어진 경우 에 대한 호출을 통해 사용자가 _signInManager.SignInAsync 로그인됩니다.

참고: 등록 시 즉시 로그인을 방지하는 단계는 계정 확인을 참조하세요.

로그인

로그인 양식은 다음과 같은 경우에 표시됩니다.

  • 로그인 링크가 선택되어 있습니다.
  • 사용자가 액세스 권한이 없거나 시스템에서 인증되지 않은 제한된 페이지에 액세스하려고 합니다.

로그인 페이지의 양식이 제출되면 OnPostAsync 작업이 호출됩니다. PasswordSignInAsync``_signInManager는 개체에서 호출됩니다.

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
    returnUrl = returnUrl ?? Url.Content("~/");

    if (ModelState.IsValid)
    {
        // This doesn't count login failures towards account lockout
        // To enable password failures to trigger account lockout, 
        // set lockoutOnFailure: true
        var result = await _signInManager.PasswordSignInAsync(Input.Email, 
            Input.Password, Input.RememberMe, lockoutOnFailure: true);
        if (result.Succeeded)
        {
            _logger.LogInformation("User logged in.");
            return LocalRedirect(returnUrl);
        }
        if (result.RequiresTwoFactor)
        {
            return RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, RememberMe = Input.RememberMe });
        }
        if (result.IsLockedOut)
        {
            _logger.LogWarning("User account locked out.");
            return RedirectToPage("./Lockout");
        }
        else
        {
            ModelState.AddModelError(string.Empty, "Invalid login attempt.");
            return Page();
        }
    }

    // If we got this far, something failed, redisplay form
    return Page();
}

권한 부여 결정을 내리는 방법에 대한 자세한 내용은 를 ASP.NET Core의 권한 부여 소개 참조하세요.

로그아웃

로그아웃 링크는 LogoutModel.OnPost 작업을 호출합니다.

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;

namespace WebApp1.Areas.Identity.Pages.Account
{
    [AllowAnonymous]
    public class LogoutModel : PageModel
    {
        private readonly SignInManager<IdentityUser> _signInManager;
        private readonly ILogger<LogoutModel> _logger;

        public LogoutModel(SignInManager<IdentityUser> signInManager, ILogger<LogoutModel> logger)
        {
            _signInManager = signInManager;
            _logger = logger;
        }

        public void OnGet()
        {
        }

        public async Task<IActionResult> OnPost(string returnUrl = null)
        {
            await _signInManager.SignOutAsync();
            _logger.LogInformation("User logged out.");
            if (returnUrl != null)
            {
                return LocalRedirect(returnUrl);
            }
            else
            {
                // This needs to be a redirect so that the browser performs a new
                // request and the identity for the user gets updated.
                return RedirectToPage();
            }
        }
    }
}

SignOutAsync는 에 저장된 사용자의 클레임을 cookie 지웁니다.

Post는 Pages/Shared/_LoginPartial.cshtml 에 지정됩니다.

@using Microsoft.AspNetCore.Identity
@inject SignInManager<IdentityUser> SignInManager
@inject UserManager<IdentityUser> UserManager

<ul class="navbar-nav">
    @if (SignInManager.IsSignedIn(User))
    {
        <li class="nav-item">
            <a class="nav-link text-dark" asp-area="Identity"
               asp-page="/Account/Manage/Index"
               title="Manage">Hello@User.Identity.Name!</a>
        </li>
        <li class="nav-item">
            <form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" 
                   asp-route-returnUrl="@Url.Page("/", new { area = "" })" 
                   method="post">
                <button type="submit" class="nav-link btn btn-link text-dark">Logout</button>
            </form>
        </li>
    }
    else
    {
        <li class="nav-item">
            <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Register">Register</a>
        </li>
        <li class="nav-item">
            <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login">Login</a>
        </li>
    }
</ul>


테스트 Identity

기본 웹 프로젝트 템플릿은 홈 페이지에 대한 익명 액세스를 허용합니다. 를 테스트하려면 Identity [Authorize] 를 페이지에 Privacy 추가합니다.

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace WebApp1.Pages
{
    [Authorize]
    public class PrivacyModel : PageModel
    {
        public void OnGet()
        {
        }
    }
}

로그인한 경우 로그아웃합니다. 앱을 실행하고 Privacy 링크를 선택합니다. 로그인 페이지로 리디렉션됩니다.

탐험 Identity

자세히 살펴보기 Identity :

Identity 요소도

모든 Identity 종속 NuGet 패키지는 Microsoft.AspNetCore.App 메타 패키지에 포함 되어 있습니다.

의 기본 패키지는 Identity AspNetCore입니다. Identity 이 패키지에는에 대 한 핵심 인터페이스 집합이 포함 되어 ASP.NET Core Identity 있으며,에 포함 되어 Microsoft.AspNetCore.Identity.EntityFrameworkCore 있습니다.

로 마이그레이션 ASP.NET Core Identity

기존 저장소 마이그레이션에 대 한 자세한 내용 및 지침은 Identity 인증 및 Identity 마이그레이션 을 참조 하세요.

암호 강도 설정

최소 암호 요구 사항을 설정 하는 예제는 구성 을 참조 하세요.

다음 단계