ASP.NET Core分布式项目实战(集成ASP.NETCore Identity)--学习笔记
任務(wù)24:集成ASP.NETCore Identity
之前在 Index 頁(yè)面寫(xiě)了一個(gè) strong 標(biāo)簽,需要加個(gè)判斷再顯示,不然為空沒(méi)有錯(cuò)誤的時(shí)候也會(huì)顯示
@if (!ViewContext.ModelState.IsValid) {<strong>Error""</strong><div asp-validation-summary="All" class="danger"></div> }因?yàn)?asp-validation-summary 是 asp.net view 視圖會(huì)自動(dòng)控制,而 strong 不會(huì),所以要顯示標(biāo)題需要添加一個(gè)判斷,那么這里我們直接移除掉,當(dāng)有錯(cuò)誤信息的時(shí)候直接顯示即可,這里作為上一節(jié)的補(bǔ)充
<div asp-validation-summary="All" class="danger"></div>這一節(jié)主要把 Identity 加入進(jìn)來(lái)
一開(kāi)始我們把 startup 中的 Identity 注釋掉了,只需要開(kāi)啟即可
添加包 IdentityServer4,IdentityServer4.AspNetIdentity,添加之后就可以把 AddTestUsers 移除掉,它就不會(huì)再用測(cè)試?yán)锩娴?user,
Startup.cs
public void ConfigureServices(IServiceCollection services) {services.AddDbContext<ApplicationDbContext>(options =>{options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));});services.AddIdentity<ApplicationUser, ApplicationUserRole>().AddEntityFrameworkStores<ApplicationDbContext>().AddDefaultTokenProviders();services.AddIdentityServer().AddDeveloperSigningCredential().AddInMemoryClients(Config.GetClients()).AddInMemoryApiResources(Config.GetApiResource()).AddInMemoryIdentityResources(Config.GetIdentityResources()).AddAspNetIdentity<ApplicationUser>();//services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)// .AddCookie(options => {// options.LoginPath = "/Account/Login";// });//services.Configure<IdentityOptions>(options =>//{// options.Password.RequireLowercase = true;// options.Password.RequireNonAlphanumeric = true;// options.Password.RequireUppercase = true;// options.Password.RequiredLength = 12;//});services.AddScoped<ConsentService>();services.AddMvc(); }接下來(lái)要到 AccountController 中切換回原先的登錄邏輯
AccountController
private UserManager<ApplicationUser> _userManager; private SignInManager<ApplicationUser> _signInManager; private IIdentityServerInteractionService _interaction;//private readonly TestUserStore _users;//public AccountController(TestUserStore users) //{ // _users = users; //}public AccountController(UserManager<ApplicationUser> userManager,SignInManager<ApplicationUser> signInManager,IIdentityServerInteractionService interaction) {_userManager = userManager;_signInManager = signInManager;_interaction = interaction; }接下來(lái)改造 AccountController 的 Register 方法,首先把 RegisterViewModel 的 UserName 改回為 Email
RegisterViewModel
public string Email { get; set; } //public string UserName { get; set; }AccountController
[HttpPost] public async Task<IActionResult> Register(RegisterViewModel registerViewModel, string returnUrl = null) {if (ModelState.IsValid){ViewData["ReturnUrl"] = returnUrl;var identityUser = new ApplicationUser{Email = registerViewModel.Email,UserName = registerViewModel.Email,NormalizedUserName = registerViewModel.Email,};var identityResult = await _userManager.CreateAsync(identityUser, registerViewModel.Password);if (identityResult.Succeeded){await _signInManager.SignInAsync(identityUser, new AuthenticationProperties { IsPersistent = true });return RedirectToLoacl(returnUrl);}else{AddErrors(identityResult);}}return View(); }接著改造 AccountController 的 Login 方法,首先把 LoginViewModel 的 UserName 也改回為 Email,并加上一個(gè) RememberMe 字段
LoginViewModel
public string Email { get; set; } //public string UserName { get; set; } public bool RememberMe { get; set; }調(diào)用 UserManager 的查找和登錄的邏輯
AccountController
[HttpPost] public async Task<IActionResult> Login(LoginViewModel loginViewModel,string returnUrl) {if (ModelState.IsValid){ViewData["ReturnUrl"] = returnUrl;var user = await _userManager.FindByEmailAsync(loginViewModel.Email);if (user == null){ModelState.AddModelError(nameof(loginViewModel.Email), "Email not exists");}else{if (await _userManager.CheckPasswordAsync(user, loginViewModel.Password)){AuthenticationProperties props = null;if (loginViewModel.RememberMe){props = new AuthenticationProperties{IsPersistent = true,ExpiresUtc = DateTimeOffset.UtcNow.Add(TimeSpan.FromMinutes(30)),};}await _signInManager.SignInAsync(user, props);if (_interaction.IsValidReturnUrl(returnUrl)){return Redirect(returnUrl);}return Redirect("~/");}ModelState.AddModelError(nameof(loginViewModel.Password), "Wrong Password");}}return View(loginViewModel); }還原 Logout 方法
Logout
public async Task<IActionResult> Logout() {await _signInManager.SignOutAsync();//await HttpContext.SignOutAsync();return RedirectToAction("Index", "Home"); }檢查一下 view,將 Login.cshtml 里面的 UserName 修改為 Email,model 改為 LoginViewModel
Login.cshtml
@model LoginViewModel;恢復(fù) Program 中 EF 的初始化
Program
public static void Main(string[] args) {BuildWebHost(args).MigrateDbContext<ApplicationDbContext>((context, services) =>{new ApplicationDbContextSeed().SeedAsync(context, services).Wait();}).Run(); }啟動(dòng)程序之后會(huì)根據(jù) appsettings.json 中的配置創(chuàng)建數(shù)據(jù)庫(kù)
appsettings.json
"ConnectionStrings": { "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-IdentitySample-CE9DD12E-9C3B-4072-8E38-6F33420849CB;Trusted_Connection=True;MultipleActiveResultSets=true" }編譯啟動(dòng)程序,可以看到用戶(hù)表有一條數(shù)據(jù)
這條數(shù)據(jù)來(lái)自 ApplicationDbContextSeed
public class ApplicationDbContextSeed {private UserManager<ApplicationUser> _userManager;public async Task SeedAsync(ApplicationDbContext context, IServiceProvider services){if (!context.Users.Any()){_userManager = services.GetRequiredService<UserManager<ApplicationUser>>();var defaultUser = new ApplicationUser {UserName="Administrator",Email ="jessetalk@163.com",NormalizedUserName ="admin"};var result = await _userManager.CreateAsync(defaultUser, "Password$123");if (!result.Succeeded){throw new Exception("初始默認(rèn)用戶(hù)失敗");}}} }瀏覽器訪問(wèn)
http://localhost:5000/使用郵箱登錄
退出登錄之后啟動(dòng)客戶(hù)端,瀏覽器訪問(wèn) 5001 之后會(huì)跳轉(zhuǎn)到 5000
http://localhost:5001/輸入郵箱和密碼之后會(huì)來(lái)到 consent 頁(yè)面
點(diǎn)擊同意之后跳轉(zhuǎn)到 MvcClient
點(diǎn)擊 About 看到用戶(hù)名是 Administrator,就是數(shù)據(jù)庫(kù)里面的用戶(hù)
這就是我們把程序里面的 TestUserStore 替換為 Identity
課程鏈接
http://video.jessetalk.cn/course/explore
相關(guān)文章
ASP.NET Core分布式項(xiàng)目實(shí)戰(zhàn)(Consent 代碼重構(gòu))--學(xué)習(xí)筆記
ASP.NET Core分布式項(xiàng)目實(shí)戰(zhàn)(Consent 確認(rèn)邏輯實(shí)現(xiàn))--學(xué)習(xí)筆記
ASP.NET Core分布式項(xiàng)目實(shí)戰(zhàn)(運(yùn)行Consent Page)--學(xué)習(xí)筆記
ASP.NET Core分布式項(xiàng)目實(shí)戰(zhàn)(Consent Controller Get請(qǐng)求邏輯實(shí)現(xiàn))--學(xué)習(xí)筆記
ASP.NET Core分布式項(xiàng)目實(shí)戰(zhàn)(Consent視圖制作)--學(xué)習(xí)筆記
ASP.NET Core分布式項(xiàng)目實(shí)戰(zhàn)(Identity Server 4回顧,Consent 實(shí)現(xiàn)思路介紹)--學(xué)習(xí)筆記
ASP.NET Core分布式項(xiàng)目實(shí)戰(zhàn)(oauth2 + oidc 實(shí)現(xiàn) client部分)--學(xué)習(xí)筆記
ASP.NET Core分布式項(xiàng)目實(shí)戰(zhàn)(oauth2 + oidc 實(shí)現(xiàn) server部分)--學(xué)習(xí)筆記
ASP.NET Core分布式項(xiàng)目實(shí)戰(zhàn)(oauth2與open id connect 對(duì)比)--學(xué)習(xí)筆記
ASP.NET Core分布式項(xiàng)目實(shí)戰(zhàn)(詳解oauth2授權(quán)碼流程)--學(xué)習(xí)筆記
ASP.NET Core分布式項(xiàng)目實(shí)戰(zhàn)(oauth密碼模式identity server4實(shí)現(xiàn))--學(xué)習(xí)筆記
ASP.NET Core分布式項(xiàng)目實(shí)戰(zhàn)(第三方ClientCredential模式調(diào)用)--學(xué)習(xí)筆記
ASP.NET Core分布式項(xiàng)目實(shí)戰(zhàn)(客戶(hù)端集成IdentityServer)--學(xué)習(xí)筆記
ASP.NET Core分布式項(xiàng)目實(shí)戰(zhàn)(業(yè)務(wù)介紹,架構(gòu)設(shè)計(jì),oAuth2,IdentityServer4)--學(xué)習(xí)筆記
ASP.NET Core分布式項(xiàng)目實(shí)戰(zhàn)(課程介紹,MVP,瀑布與敏捷)--學(xué)習(xí)筆記
ASP.NET Core快速入門(mén) -- 學(xué)習(xí)筆記匯總
總結(jié)
以上是生活随笔為你收集整理的ASP.NET Core分布式项目实战(集成ASP.NETCore Identity)--学习笔记的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 微前端与项目实施方案研究
- 下一篇: asp.net ajax控件工具集 Au