Introduction to Identity
By Pranav Rastogi, Rick Anderson, Tom Dykstra, Jon Galloway and Erik Reitan
ASP.NET Core Identity is a membership system which allows you to add login functionality to your application. Users can create an account and login with a user name and password or they can use an external login providers such as Facebook, Google, Microsoft Account, Twitter and more.
ASP.NET Core身份識別是一個成員身份管理系統,允許向應用中添加登陸功能。用戶可創建一個賬戶並進行登陸,登陸時可使用用戶名、密碼,或者使用FaceBook, Google, Microsoft Account, Twitter或者其他的外部登陸信息。
You can configure ASP.NET Core Identity to use a SQL Server database to store user names, passwords, and profile data. Alternatively, you can use your own persistent store to store data in another persistent storage, such as Azure Table Storage.
你可以通過配置ASP.NET Core的身份識別,使用SQL Server數據庫存儲用戶名字、密碼和配置文件數據。另外,你可使用其他已有的存儲空間存儲數據,例如Azure Table Storage。
Overview of Identity¶ 身份識別概述
In this topic, you’ll learn how to use ASP.NET Core Identity to add functionality to register, log in, and log out a user. You can follow along step by step or just read the details. For more detailed instructions about creating apps using ASP.NET Core Identity, see the Next Steps section at the end of this article.
本文中,你將學習如何使用ASP.NET Core身份識別技術增加注冊、登陸和注銷功能。你可以一步一步地跟着學習,也可以僅僅閱讀一些細節。更多細節請參看列在本文最后的章節提示。
- Create an ASP.NET Core Web Application project in Visual Studio with Individual User Accounts.
1. 使用Indivdual User Accounts創建應用。
In Visual Studio, select File -> New -> Project. Then, select the ASP.NET Web Application from the New Project dialog box. Continue by selecting an ASP.NET Core Web Application with Individual User Accounts as the authentication method.
在Visual Studio中, 選擇 File -> New -> Project。然后, 從New Project對話框中選擇 ASP.NET Web Application。接着選擇 ASP.NET Core Web Application, 並選擇 Individual User Accounts 身份認證功能。
The created project contains the
Microsoft.AspNetCore.Identity.EntityFrameworkCore
package, which will persist the identity data and schema to SQL Server using Entity創建的項目包含了Microsoft.AspNetCore.Identity.EntityFramewordCore包,這將使用Entity Framework Core通過SQL Server來儲存身份識別的數據和表信息。
Note
說明
In Visual Studio, you can view NuGet packages details by selecting Tools -> NuGet Package Manager -> Manage NuGet Packages for Solution. You also see a list of packages in the dependencies section of the project.json file within your project.
在VS中,你可以逐一選擇Tools -> NuGet Package Manager -> Manage NuGet Packages for Solution瀏覽NuGet包的細節。也會看到項目的project.json文件的Dependencies部分看到該包的清單。
The identity services are added to the application in the
ConfigureServices
method in theStartup
class:身份識別功能位於Startup類的ConfigureServices方法中。
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { // Add framework services. services.AddEntityFramework() .AddSqlServer() .AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"])); services.AddIdentity<ApplicationUser, IdentityRole>() .AddEntityFrameworkStores<ApplicationDbContext>() .AddDefaultTokenProviders(); services.AddMvc(); // Add application services. services.AddTransient<IEmailSender, AuthMessageSender>(); services.AddTransient<ISmsSender, AuthMessageSender>();
These services are then made available to the application through dependency injection.
這些服務通過依賴注入起作用。
Identity is enabled for the application by calling
UseIdentity
in theConfigure
method of theStartup
class. This adds cookie-based authentication to the request pipeline.通過調用Startup類Configure方法中的UseIdentity啟用身份識別。這樣,對於訪問請求就可通過cookie實現身份驗證了。
services.Configure<IdentityOptions>(options => { // Password settings options.Password.RequireDigit = true; options.Password.RequiredLength = 8; options.Password.RequireNonAlphanumeric = false; options.Password.RequireUppercase = true; options.Password.RequireLowercase = false; // Lockout settings options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30); options.Lockout.MaxFailedAccessAttempts = 10; // Cookie settings options.Cookies.ApplicationCookie.ExpireTimeSpan = TimeSpan.FromDays(150); options.Cookies.ApplicationCookie.LoginPath = "/Account/LogIn"; options.Cookies.ApplicationCookie.LogoutPath = "/Account/LogOff"; }); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(Configuration.GetSection("Logging")); loggerFactory.AddDebug(); if (env.IsDevelopment()) { app.UseBrowserLink(); app.UseDeveloperExceptionPage(); app.UseDatabaseErrorPage(); }For more information about the application start up process, see Application Startup.
- Creating a user.
2. 創建用戶
Launch the application from Visual Studio (Debug -> Start Debugging) and then click on the Register link in the browser to create a user. The following image shows the Register page which collects the user name and password.
When the user clicks the Register link, theUserManager
andSignInManager
services are injected into the Controller:當用戶點擊Register鏈接時,UserManager和SignInManager服務就被注入到控制器中:
public class AccountController : Controller { private readonly UserManager<ApplicationUser> _userManager; private readonly SignInManager<ApplicationUser> _signInManager; private readonly IEmailSender _emailSender; private readonly ISmsSender _smsSender; private static bool _databaseChecked; private readonly ILogger _logger; public AccountController( UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager, IEmailSender emailSender, ISmsSender smsSender, ILoggerFactory loggerFactory) { _userManager = userManager; _signInManager = signInManager; _emailSender = emailSender; _smsSender = smsSender; _logger = loggerFactory.CreateLogger<AccountController>(); } // // GET: /Account/Login
Then, the Register action creates the user by calling
CreateAsync
function of theUserManager
object, as shown below:接着,Register動作通過調用UserManager對象的CreateAsync函數函數創建了用戶,具體如下:
[HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<IActionResult> Register(RegisterViewModel model) { if (ModelState.IsValid) { var user = new ApplicationUser { UserName = model.Email, Email = model.Email }; var result = await _userManager.CreateAsync(user, model.Password); if (result.Succeeded) { // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=532713 // Send an email with this link //var code = await _userManager.GenerateEmailConfirmationTokenAsync(user); //var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: HttpContext.Request.Scheme); //await _emailSender.SendEmailAsync(model.Email, "Confirm your account", // "Please confirm your account by clicking this link: <a href=\"" + callbackUrl + "\">link</a>"); await _signInManager.SignInAsync(user, isPersistent: false); _logger.LogInformation(3, "User created a new account with password."); return RedirectToAction(nameof(HomeController.Index), "Home"); } AddErrors(result); } // If we got this far, something failed, redisplay form return View(model); }
- Log in.
3.登陸
If the user was successfully created, the user is logged in by the
SignInAsync
method, also contained in theRegister
action. By signing in, theSignInAsync
method stores a cookie with the user’s claims.如果成功創建了用戶,就會使用SignInAsync方法實現用戶登錄,該方法同樣包含在Register動作中。通過簽到后,SignInAsync方法使用用戶的登陸信息存儲了一個cookie。
[HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<IActionResult> Register(RegisterViewModel model) { if (ModelState.IsValid) { var user = new ApplicationUser { UserName = model.Email, Email = model.Email }; var result = await _userManager.CreateAsync(user, model.Password); if (result.Succeeded) { // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=532713 // Send an email with this link //var code = await _userManager.GenerateEmailConfirmationTokenAsync(user); //var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: HttpContext.Request.Scheme); //await _emailSender.SendEmailAsync(model.Email, "Confirm your account", // "Please confirm your account by clicking this link: <a href=\"" + callbackUrl + "\">link</a>"); await _signInManager.SignInAsync(user, isPersistent: false); _logger.LogInformation(3, "User created a new account with password."); return RedirectToAction(nameof(HomeController.Index), "Home"); } AddErrors(result); } // If we got this far, something failed, redisplay form return View(model); }
The above
SignInAsync
method calls the belowSignInAsync
task, which is contained in theSignInManager
class.上面的SignInasync方法調用了下面的SignInAsync任務,該任務包含在SingInManager類中。
If needed, you can access the user’s identity details inside a controller action. For instance, by setting a breakpoint inside the
HomeController.Index
action method, you can view theUser.claims
details. By having the user signed-in, you can make authorization decisions. For more information, see Authorization.如果需要,你可以深入控制器動作中用戶身份識別的細節。比如說,通過在HomeController.Index方法中設置斷點,就可以瀏覽User.Claims的細節。通過用戶登錄,就可以實現權限策略。
As a registered user, you can log in to the web app by clicking the Log in link. When a registered user logs in, the
Login
action of theAccountController
is called. Then, the Login action signs in the user using thePasswordSignInAsync
method contained in theLogin
action.作為注冊用戶,你可通過點擊Log in鏈接登陸應用。當注冊用戶登陸時,就調用AccountController中的Login動作。接着,Login動作使用其中的PasswordSignInAsync方法實現用戶簽到。
[HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null) { ViewData["ReturnUrl"] = returnUrl; 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(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false); if (result.Succeeded) { _logger.LogInformation(1, "User logged in."); return RedirectToLocal(returnUrl); } if (result.RequiresTwoFactor) { return RedirectToAction(nameof(SendCode), new { ReturnUrl = returnUrl, RememberMe = model.RememberMe }); } if (result.IsLockedOut) { _logger.LogWarning(2, "User account locked out."); return View("Lockout"); } else { ModelState.AddModelError(string.Empty, "Invalid login attempt."); return View(model); } } // If we got this far, something failed, redisplay form return View(model); }
- Log off.
4.登出
Clicking the Log off link calls the
LogOff
action in the account controller.點擊Log off鏈接調用賬戶控制其中的Logoff方法。
[HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> LogOff() { await _signInManager.SignOutAsync(); _logger.LogInformation(4, "User logged out."); return RedirectToAction(nameof(HomeController.Index), "Home"); }
The code above shows the
SignInManager.SignOutAsync
method. TheSignOutAsync
method clears the users claims stored in a cookie.上面顯示了SignInManager.SignOutAsyce方法中的代碼。SignOutAsync方法清除存儲在cookie中的用戶登錄信息。
- Configuration.
5.配置
Identity has some default behaviors that you can override in your application’s startup class.
身份識別具有一些默認的行為,你也可以在應用的startup類中將其重寫。
// Configure Identity services.Configure<IdentityOptions>(options => { // Password settings options.Password.RequireDigit = true; options.Password.RequiredLength = 8; options.Password.RequireNonAlphanumeric = false; options.Password.RequireUppercase = true; options.Password.RequireLowercase = false; // Lockout settings options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30); options.Lockout.MaxFailedAccessAttempts = 10; // Cookie settings options.Cookies.ApplicationCookie.ExpireTimeSpan = TimeSpan.FromDays(150); options.Cookies.ApplicationCookie.LoginPath = "/Account/LogIn"; options.Cookies.ApplicationCookie.LogoutPath = "/Account/LogOff"; });
- View the database.
6. 瀏覽數據庫
After stopping the application, view the user database from Visual Studio by selecting View -> SQL Server Object Explorer. Then, expand the following within the SQL Server Object Explorer:
- (localdb)MSSQLLocalDB
- Databases
- aspnet5-<the name of your application>
- Tables
Next, right-click the dbo.AspNetUsers table and select View Data to see the properties of the user you created.
Identity Components¶ 身份識別的組成
The primary reference assembly for the identity system is Microsoft.AspNetCore.Identity
. This package contains the core set of interfaces for ASP.NET Core Identity.
身份系統主要的引用文件包為Microsoft.AspNetCore.Identity
。其中包含了ASP.NET Core Identity的系列核心界面。
These dependencies are needed to use the identity system in ASP.NET Core applications:
需要引用ASP.NET Core中的identity system來實現這些功能。
EntityFramework.SqlServer
- Entity Framework is Microsoft’s recommended data access technology for relational databases.Microsoft.AspNetCore.Authentication.Cookies
- Middleware that enables an application to use cookie based authentication, similar to ASP.NET’s Forms Authentication.Microsoft.AspNetCore.Cryptography.KeyDerivation
- Utilities for key derivation.密鑰導出的實用程序Microsoft.AspNetCore.Hosting.Abstractions
- Hosting abstractions.托管邏輯
Migrating to ASP.NET Core Identity¶
For additional information and guidance on migrating your existing identity store see Migrating Authentication and Identity
關於遷移已有的身份識別數據,請參看Migrating Authentication and Identity
Next Steps¶
- Migrating Authentication and Identity
- Account Confirmation and Password Recovery
- Two-factor authentication with SMS
- Enabling authentication using Facebook, Google and other external providers