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 }
View Code

  通过调用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 }
View Code

注册

  当用户单击 "注册" 链接时,将调用 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 }
View Code

登录

  提交“登录”页上的表单时,会调用 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 }
View Code

注销

  "注销" 链接调用 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 }
View Code
02-12 08:35