ASP.NET Core分布式项目实战(oauth2 + oidc 实现 server部分)
文章目录
任务15:oauth2 + oidc 实现 server部分
基于之前快速入门的项目(MvcCookieAuthSample):
ASP.NET Core快速入门(第5章:认证与授权)–学习笔记
ASP.NET Core快速入门(第6章:ASP.NET Core MVC)–学习笔记
mvcCookieAuthSample2下载地址:
http://video.jessetalk.cn/course/5/material/217/download
把这个 MVC 注册登录的网站变成一个单点登录,现在它是自己登录自己使用,我们需要把它的登录信息返回给第三方
添加 identityserver4 引用
在 startup 中
using IdentityServer4;
按照之前的文章添加 Config.cs
using System.Collections; using System.Collections.Generic; using IdentityServer4.Models; using IdentityServer4.Test; namespace mvcCookieAuthSample { public class Config { public static IEnumerable<Client> GetClients() { return new List<Client> { new Client() { ClientId = "client", AllowedGrantTypes = GrantTypes.Implicit,// 隐式模式 ClientSecrets = { new Secret("secret".Sha256()) }, AllowedScopes = {"api"}, } }; } public static IEnumerable<ApiResource> GetApiResource() { return new List<ApiResource> { new ApiResource("api", "My Api") }; } public static IEnumerable<IdentityResource> GetIdentityResources() { return new List<IdentityResource> { new IdentityResources.OpenId(), new IdentityResources.Profile(), new IdentityResources.Email(), }; } public static List<TestUser> GetTestUsers() { return new List<TestUser> { new TestUser { SubjectId = "1", Username = "mingsonzheng", Password = "123456" } }; } } }
startup 的 ConfigureServices
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddIdentityServer() .AddDeveloperSigningCredential() .AddInMemoryClients(Config.GetClients()) .AddInMemoryApiResources(Config.GetApiResource()) .AddInMemoryIdentityResources(Config.GetIdentityResources()) .AddTestUsers(Config.GetTestUsers()); //services.AddDbContext<ApplicationDbContext>(options => //{ // options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")); //}); //services.AddIdentity<ApplicationUser, ApplicationUserRole>() // .AddEntityFrameworkStores<ApplicationDbContext>() // .AddDefaultTokenProviders(); //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.AddMvc(); }
startup 的 Configure 中 UseIdentityServer
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseStaticFiles(); //app.UseAuthentication(); app.UseIdentityServer(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); }
我们已经把 IdentityServer4 添加到 MVC 程序中,接着需要在 Controller 中实现这个逻辑
首先注释 AccountController 原先的登录逻辑
//private UserManager<ApplicationUser> _userManager; //private SignInManager<ApplicationUser> _signInManager;
Logout 中使用 HttpContext.SignOutAsync 替换
public async Task<IActionResult> Logout() { //await _signInManager.SignOutAsync(); await HttpContext.SignOutAsync(); return RedirectToAction("Index", "Home"); }
接着改造登录的逻辑,我们需要验证用户名和密码,前面我们在 Config 中添加了 TestUser,它被放在 TestUserStore 中,可以通过依赖注入引用进来,有了它之后就可以在登录的时候拿到用户名和密码
private readonly TestUserStore _users; public AccountController(TestUserStore users) { _users = users; }
因为 TestUser 本身不提供 Email 登录,所以我们需要修改 LoginViewModel 以及 Login.cshtml
LoginViewModel
[Required] //[DataType(DataType.EmailAddress)] //public string Email { get; set; } public string UserName { get; set; }
Login.cshtml
<div class="form-group"> <label asp-for="UserName"></label> <input asp-for="UserName" class="form-control" /> <span asp-validation-for="UserName" class="text-danger"></span> </div>
改造登录的逻辑
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 //{ // await _signInManager.SignInAsync(user, new AuthenticationProperties { IsPersistent = true }); // return RedirectToLoacl(returnUrl); //} ViewData["ReturnUrl"] = returnUrl; var user = _users.FindByUsername(loginViewModel.UserName); if (user == null) { ModelState.AddModelError(nameof(loginViewModel.UserName), "UserName not exists"); } else { if (_users.ValidateCredentials(loginViewModel.UserName, loginViewModel.Password)) { var props = new AuthenticationProperties { IsPersistent = true, ExpiresUtc = DateTimeOffset.UtcNow.Add(TimeSpan.FromMinutes(30)), }; await Microsoft.AspNetCore.Http.AuthenticationManagerExtensions.SignInAsync( HttpContext, user.SubjectId, user.Username, props ); return RedirectToLoacl(returnUrl); } ModelState.AddModelError(nameof(loginViewModel.Password), "Wrong Password"); } } return View(); }
这样,我们就实现了一个通过 IdentityServer4 下的方法来实现了一个登录逻辑,然后做了一个跳转,下一节再把客户端加进来
课程链接
http://video.jessetalk.cn/course/explore
相关文章
ASP.NET Core分布式项目实战(oauth2与open id connect 对比)–学习笔记
ASP.NET Core分布式项目实战(详解oauth2授权码流程)–学习笔记
ASP.NET Core分布式项目实战(oauth密码模式identity server4实现)–学习笔记
ASP.NET Core分布式项目实战(第三方ClientCredential模式调用)–学习笔记
ASP.NET Core分布式项目实战(客户端集成IdentityServer)–学习笔记
ASP.NET Core分布式项目实战(业务介绍,架构设计,oAuth2,IdentityServer4)–学习笔记
ASP.NET Core分布式项目实战(课程介绍,MVP,瀑布与敏捷)–学习笔记
ASP.NET Core快速入门 — 学习笔记汇总
欢迎各位读者加入微信群一起学习交流,在公众号后台回复“加群”即可~~

原文出处:微信公众号【郑子铭 DotNet NB】
原文链接:https://mp.weixin.qq.com/s/oVy96FMfjyKpmV4doU-fsg
本文观点不代表Dotnet9立场,转载请联系原作者。