ASP.NET Core Identity是一个成员资格系统(membership system),该系统将登录功能添加到 ASP.NET Core 应用中。 用户可以创建一个具有登录信息的帐户并存储在Identity中,该系统支持包括Facebook、Google、Microsoft 帐户和 Twitter等外部登录提供程序。
ASP.NET Core 2.1 中引入了AddDefaultIdentity 。 调用 AddDefaultIdentity
类似于调用以下内容:
配置Identity服务
服务添加到 ConfigureServices
。 典型模式是调用所有 Add{Service}
方法,然后调用所有 services.Configure{Service}
方法。
1 public void ConfigureServices(IServiceCollection services) 2 { 3 services.Configure<CookiePolicyOptions>(options => 4 { 5 options.CheckConsentNeeded = context => true; 6 options.MinimumSameSitePolicy = SameSiteMode.None; 7 }); 8 9 services.AddDbContext<ApplicationDbContext>(options => 10 options.UseSqlServer( 11 Configuration.GetConnectionString("DefaultConnection"))); 12 services.AddDefaultIdentity<IdentityUser>() 13 .AddDefaultUI(UIFramework.Bootstrap4) 14 .AddEntityFrameworkStores<ApplicationDbContext>(); 15 16 services.Configure<IdentityOptions>(options => 17 { 18 // Password settings. 19 options.Password.RequireDigit = true; 20 options.Password.RequireLowercase = true; 21 options.Password.RequireNonAlphanumeric = true; 22 options.Password.RequireUppercase = true; 23 options.Password.RequiredLength = 6; 24 options.Password.RequiredUniqueChars = 1; 25 26 // Lockout settings. 27 options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5); 28 options.Lockout.MaxFailedAccessAttempts = 5; 29 options.Lockout.AllowedForNewUsers = true; 30 31 // User settings. 32 options.User.AllowedUserNameCharacters = 33 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+"; 34 options.User.RequireUniqueEmail = false; 35 }); 36 37 services.ConfigureApplicationCookie(options => 38 { 39 // Cookie settings 40 options.Cookie.HttpOnly = true; 41 options.ExpireTimeSpan = TimeSpan.FromMinutes(5); 42 43 options.LoginPath = "/Identity/Account/Login"; 44 options.AccessDeniedPath = "/Identity/Account/AccessDenied"; 45 options.SlidingExpiration = true; 46 }); 47 48 services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); 49 }
通过调用UseAuthentication来启用标识。UseAuthentication
会将身份验证中间件添加到请求管道。
1 public void Configure(IApplicationBuilder app, IHostingEnvironment env) 2 { 3 if (env.IsDevelopment()) 4 { 5 app.UseDeveloperExceptionPage(); 6 app.UseDatabaseErrorPage(); 7 } 8 else 9 { 10 app.UseExceptionHandler("/Error"); 11 app.UseHsts(); 12 } 13 14 app.UseHttpsRedirection(); 15 app.UseStaticFiles(); 16 app.UseCookiePolicy(); 17 18 app.UseAuthentication(); 19 20 app.UseMvc(); 21 }
注册
当用户单击 "注册" 链接时,将调用 RegisterModel.OnPostAsync
操作。 用户由CreateAsync在 _userManager
对象上创建。 _userManager
由依赖关系注入提供):
1 public async Task<IActionResult> OnPostAsync(string returnUrl = null) 2 { 3 returnUrl = returnUrl ?? Url.Content("~/"); 4 if (ModelState.IsValid) 5 { 6 var user = new IdentityUser { UserName = Input.Email, Email = Input.Email }; 7 var result = await _userManager.CreateAsync(user, Input.Password); 8 if (result.Succeeded) 9 { 10 _logger.LogInformation("User created a new account with password."); 11 12 var code = await _userManager.GenerateEmailConfirmationTokenAsync(user); 13 var callbackUrl = Url.Page( 14 "/Account/ConfirmEmail", 15 pageHandler: null, 16 values: new { userId = user.Id, code = code }, 17 protocol: Request.Scheme); 18 19 await _emailSender.SendEmailAsync(Input.Email, "Confirm your email", 20 $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>."); 21 22 await _signInManager.SignInAsync(user, isPersistent: false); 23 return LocalRedirect(returnUrl); 24 } 25 foreach (var error in result.Errors) 26 { 27 ModelState.AddModelError(string.Empty, error.Description); 28 } 29 } 30 31 // If we got this far, something failed, redisplay form 32 return Page(); 33 }
登录
提交“登录”页上的表单时,会调用 OnPostAsync
操作。 会在 _signInManager
对象(通过注入依赖项的方式提供)上调用 PasswordSignInAsync
。
1 public async Task<IActionResult> OnPostAsync(string returnUrl = null) 2 { 3 returnUrl = returnUrl ?? Url.Content("~/"); 4 5 if (ModelState.IsValid) 6 { 7 // This doesn't count login failures towards account lockout 8 // To enable password failures to trigger account lockout, 9 // set lockoutOnFailure: true 10 var result = await _signInManager.PasswordSignInAsync(Input.Email, 11 Input.Password, Input.RememberMe, lockoutOnFailure: true); 12 if (result.Succeeded) 13 { 14 _logger.LogInformation("User logged in."); 15 return LocalRedirect(returnUrl); 16 } 17 if (result.RequiresTwoFactor) 18 { 19 return RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, RememberMe = Input.RememberMe }); 20 } 21 if (result.IsLockedOut) 22 { 23 _logger.LogWarning("User account locked out."); 24 return RedirectToPage("./Lockout"); 25 } 26 else 27 { 28 ModelState.AddModelError(string.Empty, "Invalid login attempt."); 29 return Page(); 30 } 31 } 32 33 // If we got this far, something failed, redisplay form 34 return Page(); 35 }
注销
"注销" 链接调用 LogoutModel.OnPost
操作。
1 using Microsoft.AspNetCore.Authorization; 2 using Microsoft.AspNetCore.Identity; 3 using Microsoft.AspNetCore.Mvc; 4 using Microsoft.AspNetCore.Mvc.RazorPages; 5 using Microsoft.Extensions.Logging; 6 using System.Threading.Tasks; 7 8 namespace WebApp1.Areas.Identity.Pages.Account 9 { 10 [AllowAnonymous] 11 public class LogoutModel : PageModel 12 { 13 private readonly SignInManager<IdentityUser> _signInManager; 14 private readonly ILogger<LogoutModel> _logger; 15 16 public LogoutModel(SignInManager<IdentityUser> signInManager, ILogger<LogoutModel> logger) 17 { 18 _signInManager = signInManager; 19 _logger = logger; 20 } 21 22 public void OnGet() 23 { 24 } 25 26 public async Task<IActionResult> OnPost(string returnUrl = null) 27 { 28 await _signInManager.SignOutAsync(); 29 _logger.LogInformation("User logged out."); 30 if (returnUrl != null) 31 { 32 return LocalRedirect(returnUrl); 33 } 34 else 35 { 36 // This needs to be a redirect so that the browser performs a new 37 // request and the identity for the user gets updated. 38 return RedirectToPage(); 39 } 40 } 41 } 42 }