任务24:集成ASP.NETCore Identity

之前在 Index 页面写了一个 strong 标签,需要加个判断再显示,不然为空没有错误的时候也会显示

@if (!ViewContext.ModelState.IsValid)
{<strong>Error""</strong><div asp-validation-summary="All" class="danger"></div>
}

因为 asp-validation-summary 是 asp.net view 视图会自动控制,而 strong 不会,所以要显示标题需要添加一个判断,那么这里我们直接移除掉,当有错误信息的时候直接显示即可,这里作为上一节的补充

<div asp-validation-summary="All" class="danger"></div>

这一节主要把 Identity 加入进来

一开始我们把 startup 中的 Identity 注释掉了,只需要开启即可

添加包 IdentityServer4,IdentityServer4.AspNetIdentity,添加之后就可以把 AddTestUsers 移除掉,它就不会再用测试里面的 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();
}

接下来要到 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;
}

接下来改造 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,并加上一个 RememberMe 字段

LoginViewModel

public string Email { get; set; }
//public string UserName { get; set; }
public bool RememberMe { get; set; }

调用 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;

恢复 Program 中 EF 的初始化

Program

public static void Main(string[] args)
{BuildWebHost(args).MigrateDbContext<ApplicationDbContext>((context, services) =>{new ApplicationDbContextSeed().SeedAsync(context, services).Wait();}).Run();
}

启动程序之后会根据 appsettings.json 中的配置创建数据库

appsettings.json

"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-IdentitySample-CE9DD12E-9C3B-4072-8E38-6F33420849CB;Trusted_Connection=True;MultipleActiveResultSets=true"
}

编译启动程序,可以看到用户表有一条数据

这条数据来自 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("初始默认用户失败");}}}
}

浏览器访问

http://localhost:5000/

使用邮箱登录

退出登录之后启动客户端,浏览器访问 5001 之后会跳转到 5000

http://localhost:5001/

输入邮箱和密码之后会来到 consent 页面

点击同意之后跳转到 MvcClient

点击 About 看到用户名是 Administrator,就是数据库里面的用户

这就是我们把程序里面的 TestUserStore 替换为 Identity

课程链接

http://video.jessetalk.cn/course/explore

相关文章

ASP.NET Core分布式项目实战(Consent 代码重构)--学习笔记

ASP.NET Core分布式项目实战(Consent 确认逻辑实现)--学习笔记

ASP.NET Core分布式项目实战(运行Consent Page)--学习笔记

ASP.NET Core分布式项目实战(Consent Controller Get请求逻辑实现)--学习笔记

ASP.NET Core分布式项目实战(Consent视图制作)--学习笔记

ASP.NET Core分布式项目实战(Identity Server 4回顾,Consent 实现思路介绍)--学习笔记

ASP.NET Core分布式项目实战(oauth2 + oidc 实现 client部分)--学习笔记

ASP.NET Core分布式项目实战(oauth2 + oidc 实现 server部分)--学习笔记

ASP.NET Core分布式项目实战(oauth2与open id connect 对比)--学习笔记

ASP.NET Core分布式项目实战(详解oauth2授权码流程)--学习笔记

ASP.NET Core分布式项目实战(oauth密码模式identity server4实现)--学习笔记

ASP.NET&nbsp;Core分布式项目实战(第三方ClientCredential模式调用)--学习笔记

ASP.NET Core分布式项目实战(客户端集成IdentityServer)--学习笔记

ASP.NET Core分布式项目实战(业务介绍,架构设计,oAuth2,IdentityServer4)--学习笔记

ASP.NET Core分布式项目实战(课程介绍,MVP,瀑布与敏捷)--学习笔记

ASP.NET Core快速入门 -- 学习笔记汇总

ASP.NET Core分布式项目实战(集成ASP.NETCore Identity)--学习笔记相关推荐

  1. ASP.NET Core分布式项目实战(客户端集成IdentityServer)--学习笔记

    任务9:客户端集成IdentityServer 新建 API 项目 dotnet new webapi --name ClientCredentialApi 控制器添加验证 using Microso ...

  2. ASP.NET Core分布式项目实战(Consent 确认逻辑实现)--学习笔记

    任务22:Consent 确认逻辑实现 接下来,我们会在上一节的基础上添加两个按钮,同意和不同意,点击之后会把请求 post 到 ConsentController 处理,如果同意会通过 return ...

  3. ASP.NET Core分布式项目实战(运行Consent Page)--学习笔记

    任务21:运行Consent Page 修改 Config.cs 中的 RequireConsent 为 true,这样登录的时候就会跳转到 Consent 页面 修改 ConsentControll ...

  4. ASP.NET Core分布式项目实战(Consent Controller Get请求逻辑实现)--学习笔记

    任务20:Consent Controller Get请求逻辑实现 接着上一节的思路,实现一下 ConsentController 根据流程图在构造函数注入 IClientStore,IResourc ...

  5. ASP.NET Core分布式项目实战(oauth2 + oidc 实现 client部分)--学习笔记

    任务16:oauth2 + oidc 实现 client部分 实现 client 之前启动一下上一节的 server,启动之前需要清除一些代码 注释 Program 的 MigrateDbContex ...

  6. ASP.NET Core分布式项目实战(oauth2 + oidc 实现 server部分)--学习笔记

    任务15:oauth2 + oidc 实现 server部分 基于之前快速入门的项目(MvcCookieAuthSample): ASP.NET Core快速入门(第5章:认证与授权)--学习笔记 A ...

  7. ASP.NET Core分布式项目实战(详解oauth2授权码流程)--学习笔记

    最近公司产品上线,通宵加班了一个月,一直没有更新,今天开始恢复,每日一更,冲冲冲 任务13:详解oauth2授权码流程 我们即将开发的产品有一个用户 API,一个项目服务 API,每个服务都需要认证授 ...

  8. ASP.NET Core分布式项目实战(第三方ClientCredential模式调用)--学习笔记

    任务10:第三方ClientCredential模式调用 创建一个控制台程序 dotnet new console --name ThirdPartyDemo 添加 Nuget 包:IdentityM ...

  9. ASP.NET Core分布式项目实战(业务介绍,架构设计,oAuth2,IdentityServer4)--学习笔记...

    任务4:第一章计划与目录 敏捷产品开发流程 原型预览与业务介绍 整体架构设计 API 接口设计 / swagger Identity Server 4 搭建登录 账号 API 实现 配置中心 任务5: ...

最新文章

  1. Python学习笔记2 基本数据类型
  2. 树莓派下安装Django环境
  3. css实现元素水平垂直居中
  4. Shopify 英文(多国语言)国际网店 注册指南
  5. mysql 增量备份_MySQL增量备份与恢复(增量备份概述、特点,断点恢复实操)
  6. C++ 简单的SQL注入过滤
  7. python jieba库的使用
  8. 计算机优先启动项,大白菜u盘装系统bios设置优先启动项操作方法
  9. SSL证书中DV证书、OV证书和EV证书的区别
  10. CSU1256 天朝的单行道(spfa)
  11. 电脑上如何禁止一切弹窗广告?永久关闭桌面弹出广告
  12. mysql字符集修改无效,Mysql字符集的修改及查看问题_MySQL
  13. 杰卡德相似系数(Jaccardsimilarity coefficient)
  14. 为电子书产品赋予新的定义,两款高端电子书横评
  15. 预测未来的神技——有趣的马尔科夫链
  16. Unity之UGUI脚本自动生成
  17. [转]梧州--没有眼泪!!
  18. 【Paper Reading】Privacy-Preserving Aggregation in Federated Learning: A Survey
  19. RC522 读卡器和写卡器 读写测试程序----基于cc2530开发板
  20. 一台服务器想用150个ip,可以吗?

热门文章

  1. 项目手札2---关于分页显示时地址栏的风格
  2. 研究生计划-心得征程
  3. Log4net数据表
  4. java 中的 io 系统总结
  5. 遭遇“烧钱瓶颈” 优酷成本结构堪忧
  6. 如何在Windows 7或Vista上安装IIS
  7. Codeforces Round #358 (Div. 2) A. Alyona and Numbers 水题
  8. Android JSON原生解析的几种思路,以号码归属地,笑话大全,天气预报为例演示...
  9. java基础巩固笔记(6)-注解
  10. 第十六周项目3-有相同数字?