任务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

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

欢迎转载、使用、重新发布,但务必保留文章署名 郑子铭 (包含链接: http://www.cnblogs.com/MingsonZheng/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。

如有任何疑问,请与我联系 (MingsonZheng@outlook.com) 。

ASP.NET Core分布式项目实战(集成ASP.NETCore Identity)--学习笔记的更多相关文章

  1. ASP.NET Core分布式项目实战

    ASP.NET Core开发者成长路线图 asp.net core 官方文档 https://docs.microsoft.com/zh-cn/aspnet/core/getting-started/ ...

  2. 【笔记目录2】ASP.NET Core分布式项目实战

    当前标签: ASP.NET Core分布式项目实战 共2页: 上一页 1 2  11.ClientCredential模式总结 GASA 2019-03-11 12:59 阅读:26 评论:0 10. ...

  3. 【笔记目录1】ASP.NET Core分布式项目实战

    当前标签: ASP.NET Core分布式项目实战 共2页: 1 2 下一页  35.Docker安装Mysql挂载Host Volume GASA 2019-06-20 22:02 阅读:51 评论 ...

  4. ASP.NET Core分布式项目-2.oauth密码模式identity server4实现

    源码下载 这里根据<ASP.NET Core分布式项目-1.IdentityServer4登录中心>的代码来继续更新oauth密码模式,这里的密码模式比上次的客户端模式更安全 在WebAp ...

  5. 【ASP.NET Core分布式项目实战】(三)整理IdentityServer4 MVC授权、Consent功能实现

    本博客根据http://video.jessetalk.cn/my/course/5视频整理(内容可能会有部分,推荐看源视频学习) 前言 由于之前的博客都是基于其他的博客进行开发,现在重新整理一下方便 ...

  6. ASP.NET Core分布式项目实战-目录

    前言 今年是2018年,发现已经有4年没有写博客了,在这4年的时光里,接触了很多的.NET技术,自己的技术也得到很大的进步.在这段时光里面很感谢张队长以及其他开发者一直对.NET Core开源社区做出 ...

  7. 【ASP.NET Core分布式项目实战】(一)IdentityServer4登录中心、oauth密码模式identity server4实现

    本博客根据http://video.jessetalk.cn/my/course/5视频整理 资料 OAuth2 流程:http://www.ruanyifeng.com/blog/2014/05/o ...

  8. 【ASP.NET Core分布式项目实战】(五)Docker制作dotnet core控制台程序镜像

    Docker制作dotnet core控制台程序镜像 基于dotnet SDK 新建控制台程序 mkdir /home/console cd /home/console dotnet new cons ...

  9. 【ASP.NET Core分布式项目实战】(六)Gitlab安装

    Gitlab GitLab是由GitLabInc.开发,使用MIT许可证的基于网络的Git仓库管理工具,且具有wiki和issue跟踪功能.使用Git作为代码管理工具,并在此基础上搭建起来的web服务 ...

  10. 【ASP.NET Core分布式项目实战】(二)oauth2 + oidc 实现 server部分

    本博客根据http://video.jessetalk.cn/my/course/5视频整理(内容可能会有部分,推荐看源视频学习) 资料 我们基于之前的MvcCookieAuthSample来做开发 ...

随机推荐

  1. 【vue基础篇】一看就懂的vue环境变量配置

    相关播客地址: https://juejin.cn/post/6844903859878363149 https://juejin.cn/post/6844903682178285575 视频学习资料 ...

  2. C#语言 十大经典排序算法动画与解析!(动态演示+代码)(java改写成C# )

    以下内容是根据 https://www.cnblogs.com/fivestudy/p/10212306.html   进行改写 排序算法是<数据结构与算法>中最基本的算法之一. 排序算法 ...

  3. 每天学五分钟 Liunx 0100 | 服务篇:进程状态

    多任务和 CPU 时间片 前面说了 Liunx 是多用户多任务的,所谓的多任务就是多个进程"同时"执行.比如,同时开多个软件(进程),对于用户来说好像每个软件(进程)都在工作,但是 ...

  4. 分享Go书籍-《Go Web编程》

    大家好,我是沙漠尽头的狼. 最近几天在看一本Go的书籍,看了100来页,感觉不错,分享给大家​.​ 书籍基本信息 书籍信息: 书名:Go Web编程 作 者:(新加坡)郑兆雄(Sau Sheong C ...

  5. ONVIF网络摄像头(IPC)客户端开发—RTSP RTCP RTP加载AAC音频流

    前言: RTSP,RTCP,RTP一般是一起使用,在FFmpeg和live555这些库中,它们为了更好的适用性,所以实现起来非常复杂,直接查看FFmpeg和Live555源代码来熟悉这些协议非常吃力, ...

  6. CPU信息查看的工具

    CPU信息查看的工具 背景 信创国产化如火如荼. CPU的型号其实越来越多 lscpu出来的结果其实太抽象, 对CPU的缓存架构显示不充分 今天在看大佬的文章是看到了一个工具: hwloc 感觉非常优 ...

  7. nexus的简单安装与使用

    nexus的简单安装与使用 文件下载 官网上面下载文件比较麻烦, 得科学一些 https://www.sonatype.com/download-oss-sonatype 选择oss 开源版进行下载 ...

  8. [转帖]Python学习之十七_django的入门

    Python学习之十七_django的入门 前言 Python学习了一周, 慢慢总结摸索. 自己还是有多不会的地方. 感慨这些年浪费的时间. 所有的时间都是选择大于努力. 努力最多感动自己. 生活是需 ...

  9. [转帖]金仓数据库KingbaseES V8R6索引坏块故障处理

    案例说明: 在执行表数据查询时,出现下图所示错误,索引故障导致表无法访问,后重建索引问题解决.本案例复现了此类故障解决过程. 适用版本: KingbaseES V8R3/R6 一.创建测试环境 # 表 ...

  10. ESXi虚拟化的坑-细微区别下虚拟机性能差异巨大

    ESXi虚拟化的坑-细微区别下虚拟机性能差异巨大 背景 周末在公司无偿加班. 同组的小伙伴周一有一个需求, 我想着周六乘着机器压力不大进行一下虚拟机的clone 但是截止到晚上快十点都没有完全Clon ...