关键词:
原文:【ASP.NET Core分布式项目实战】(二)oauth2 + oidc 实现 server部分本博客根据http://video.jessetalk.cn/my/course/5视频整理(内容可能会有部分,推荐看源视频学习)
资料
我们基于之前的MvcCookieAuthSample来做开发
MvcCookieAuthSample下载地址:https://files.cnblogs.com/files/wyt007/ASPNETCore%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8.rar
MvcCookieAuthSample教程地址:http://www.cnblogs.com/wyt007/p/8204731.html
正文
给网站设置默认地址 http://localhost:5000
首先,我们将之前写的系统的Identity注释掉,在Startup.cs中
第一步:添加Nuget包:IdentityServer4
我们可以在vscode中使用ctrl+P键来打开命令面板。然后输入nuget按回车,输入identityserver4后按回车来选择版本进行安装
第二步:添加Config.cs配置类
我们接下来添加一个Config.cs类,这个类是用来初始化IdentityServer的
using System.Collections; using System.Collections.Generic; using IdentityServer4; using IdentityServer4.Models; using IdentityServer4.Test; namespace MvcCookieAuthSample public class Config //所有可以访问的Resource public static IEnumerable<ApiResource> GetApiResources() return new List<ApiResource> new ApiResource("api1","API Application") ; //客户端 public static IEnumerable<Client> GetClients() return new List<Client> new Client() ClientId="mvc", AllowedGrantTypes= GrantTypes.Implicit,//模式:最简单的模式 ClientSecrets=//私钥 new Secret("secret".Sha256()) , AllowedScopes=//可以访问的Resource IdentityServerConstants.StandardScopes.Profile, IdentityServerConstants.StandardScopes.OpenId, , RedirectUris="http://localhost:5001/signin-oidc",//跳转登录到的客户端的地址 PostLogoutRedirectUris="http://localhost:5001/signout-callback-oidc",//跳转登出到的客户端的地址 RequireConsent=false//是否需要用户点击确认进行跳转 ; //测试用户 public static List<TestUser> GetTestUsers() return new List<TestUser> new TestUser SubjectId="10000", Username="wyt", Password="password" ; //定义系统中的资源 public static IEnumerable<IdentityResource> GetIdentityResources() return new List<IdentityResource> new IdentityResources.OpenId(), new IdentityResources.Profile(), new IdentityResources.Email() ;
以上使用IdentityServer4测试数据类添加数据,直接存在内存中。IdentityServer4 是支持持久化。
第三步:添加Startup配置
引用命名空间:
using IdentityServer4;
然后打开Startup.cs 加入如下:
services.AddIdentityServer() .AddDeveloperSigningCredential()//添加开发人员签名凭据 .AddInMemoryApiResources(Config.GetApiResources())//添加内存apiresource .AddInMemoryClients(Config.GetClients())//添加内存client .AddInMemoryIdentityResources(Config.GetIdentityResources())//添加系统中的资源 .AddTestUsers(Config.GetTestUsers());//添加测试用户
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) ... //app.UseAuthentication(); app.UseIdentityServer(); ...
接着安装UI,UI部分也可以自己编写,也就是登录 注销 允许和错误。
可以到 https://github.com/IdentityServer/IdentityServer4.Quickstart.UI/tree/release 下载,然后解压到项目目录下。
也可以使用命令提示符快速安装:
powershell iex ((New-Object System.Net.WebClient).DownloadString(‘https://raw.githubusercontent.com/IdentityServer/IdentityServer4.Quickstart.UI/release/get.ps1‘))
在项目目录下打开命令提示符,输入以上命令。
更多信息,可以查看官方readme:https://github.com/IdentityServer/IdentityServer4.Quickstart.UI/blob/release/README.md
大神博客:https://www.cnblogs.com/linezero/p/identityserver4openidconnect.html
修改LoginViewModel,将Email改为UserName,并修改强类型视图的引用部分Login.cshtml
namespace MvcCookieAuthSample.ViewModels public class LoginViewModel //[Required]//必须的 //[DataType(DataType.EmailAddress)]//内容检查是否为邮箱 //public string Email get; set; [Required] public string UserName get; set; [Required]//必须的 [DataType(DataType.Password)]//内容检查是否为密码 public string Password get; set;
修改AccountController,原来的_userManager和_signInManager不再使用
using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authentication.Cookies; using System.Security.Claims; using Microsoft.AspNetCore.Mvc; using System.Collections.Generic; using Microsoft.AspNetCore.Identity; using MvcCookieAuthSample.Models; using System.Threading.Tasks; using MvcCookieAuthSample.ViewModels; using IdentityServer4.Test; using System; namespace MvcCookieAuthSample.Controllers public class AccountController : Controller // private UserManager<ApplicationUser> _userManager;//创建用户的 // private SignInManager<ApplicationUser> _signInManager;//用来登录的 private readonly TestUserStore _users; public AccountController(TestUserStore users) _users=users; // //依赖注入 // public AccountController(UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager) // // _userManager = userManager; // _signInManager = signInManager; // //内部跳转 private IActionResult RedirectToLocal(string returnUrl) if (Url.IsLocalUrl(returnUrl)) //如果是本地 return Redirect(returnUrl); return RedirectToAction(nameof(HomeController.Index), "Home"); //添加验证错误 private void AddError(IdentityResult result) //遍历所有的验证错误 foreach (var error in result.Errors) //返回error到model ModelState.AddModelError(string.Empty, error.Description); public IActionResult Register(string returnUrl = null) ViewData["returnUrl"] = returnUrl; return View(); [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) // // //注册完成登录生成cookies信息 // await _signInManager.SignInAsync(identityUser, new AuthenticationProperties IsPersistent = true ); // return RedirectToLocal(returnUrl); // // else//注册失败 // // //添加验证错误 // AddError(identityResult); // // return View(); public IActionResult Login(string returnUrl = null) ViewData["returnUrl"] = returnUrl; return View(); [HttpPost] public async Task<IActionResult> Login(LoginViewModel loginViewModel, string returnUrl = null) if (ModelState.IsValid) ViewData["returnUrl"] = returnUrl; //var user = await _userManager.FindByEmailAsync(loginViewModel.Email); 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 prop = new AuthenticationProperties() IsPersistent = true, ExpiresUtc = DateTimeOffset.UtcNow.Add(TimeSpan.FromMinutes(30)) ; //HttpContext.SignInAsync(user.SubjectId, user.Username, prop); await Microsoft.AspNetCore.Http.AuthenticationManagerExtensions.SignInAsync(HttpContext, user.SubjectId, user.Username, prop); //账号密码先不做验证,需要可以自己写 //await _signInManager.SignInAsync(user, new AuthenticationProperties IsPersistent = true ); return RedirectToLocal(returnUrl); return View(); //登出 public async Task<IActionResult> Logout() await HttpContext.SignOutAsync(); return RedirectToAction("Index", "Home");
接下来我们需要将原来的Program.cs中的数据库初始化的内容注释掉
然后我们就可以运行网站,输入用户名和密码进行登录了
新建客户端
新建一个MVC网站MvcClient
dotnet new mvc --name MvcClient
给网站设置默认地址 http://localhost:5001
MVC的网站已经内置帮我们实现了Identity,所以我们不需要再额外添加Identity引用
添加认证
services.AddAuthentication(options => options.DefaultScheme = "Cookies";//使用Cookies认证 options.DefaultChallengeScheme = "oidc";//使用oidc ) .AddCookie("Cookies")//配置Cookies认证 .AddOpenIdConnect("oidc",options=> //配置oidc options.SignInScheme = "Cookies"; options.Authority = "http://localhost:5000"; options.RequireHttpsMetadata = false; options.ClientId = "mvc"; options.ClientSecret = "secret"; options.SaveTokens = true; );
在管道中使用Authentication
app.UseAuthentication();
接下来我们在HomeController上打上 [Authorize] 标签,然后启动运行
我们这个时候访问首页http://localhost:5001会自动跳转到ocalhost:5000/account/login登录
登录之后会自动跳转回来
我们可以在Home/About页面将claim的信息显示出来
@ ViewData["Title"] = "About"; <h2>@ViewData["Title"]</h2> <h3>@ViewData["Message"]</h3> <dl> @foreach (var claim in User.Claims) <dt>@claim.Type</dt> <dt>@claim.Value</dt> </dl>
这边的内容是根据我们在IdentityServer服务中定义的返回资源决定的
asp.netcore分布式项目实战整理identityserver4mvc授权consent功能实现(代码片段)
原文:【ASP.NETCore分布式项目实战】(三)整理IdentityServer4MVC授权、Consent功能实现本博客根据http://video.jessetalk.cn/my/course/5视频整理(内容可能会有部分,推荐看源视频学习)前言由于之前的博客都是基于其他的博客进行开发,现... 查看详情
无私分享:asp.netcore项目实战(第十二章)添加对sqlservermysqloracle的支持
...对多种数据库操作,这可能需要多个上下文,暂且不论。分布式数据库,我们采用的是阿里云的Mycat,这个后面会更新出来。我们今天的场景是:我们的项目可能是在windows上开发的使用的是SqlServ 查看详情
asp.netcore系列6实战之一个项目的完整结构(代码片段)
0.前言在《asp.netcore系列》之前的几篇文章中,我们简单了解了路由、控制器以及视图的关系以及静态资源的引入,让我们对于asp.netcoremvc项目有了基本的认识。不过,这些并不是asp.netcoremvc项目的全部内容,剩下的内容我将结合... 查看详情
asp.netcore中间件详解及项目实战(代码片段)
原文:ASP.NETCore中间件详解及项目实战前言在上篇文章主要介绍了DotNetCore项目状况,本篇文章是我们在开发自己的项目中实际使用的,比较贴合实际应用,算是对中间件的一个深入使用了,不是简单的HelloWorld,如果你觉得本篇文... 查看详情
asp.netcore项目实战之权限管理系统无中生有
...发一个普通的权限管理系统的方式来从零体验和学习Asp.netCore。项目的整体规划大致如下:技术路线Asp.netCoreMvcEntityFrameworkCoreBootstrapAdminLTEPostgreSQL实现功能组织机构管理角色管理用户管理功能管理权限 查看详情
netcore体系-web应用程序-4asp.netcore2.0项目实战-2项目说明和源码下载
...行 3.linux下运行4.开发记录5.总结1.概要 写《Asp.NetCore2.0项目实战》系列断断续续已经很长时间了,期间很多朋友要求开放源码,但是项目代码一直有很多问题,就算勉强开源出来大家看起来也比较费劲,运行起来也看不... 查看详情
netcore体系-web应用程序-4asp.netcore2.0项目实战-3项目架构说明(代码片段)
...4.总结1. 摘要 NCMVC角色权限管理框架是由最近练习NetCore时抽时间整理的系统,后续能不能发展成一个cms还要看朋友们是否有需要或时间是否充实。这里NCMVC主要还是给想要学习接触Asp.NetCore2.0的朋友们提供一些借鉴以及坑... 查看详情
netcore使用mycat分布式数据库,实现读写分离
netCore使用MyCat分布式数据库,实现读写分离目录索引 【无私分享:ASP.NETCORE项目实战】目录索引 简介 MyCat2.0版本很快就发布了,关于MyCat的动态和一些问题,大家可以加一下MyCat的官方QQ群:106088787。我们... 查看详情
netcore项目实战之权限管理系统
...发一个普通的权限管理系统的方式来从零体验和学习Asp.netCore。项目的整体规划大致如下:技术路线Asp.netCoreMvcEntityFrameworkCoreBootstrapAdminLTEPostgreSQL实现功能组织机构管理角色管理用户管理功能 查看详情
netcore体系-web应用程序-4asp.netcore2.0项目实战-5项目数据库操作封装操作(代码片段)
...作封装类 3.EFCore数据库操作4.总结1. 摘要 Asp.NetCore2.0下操作MSSQL数据库,这里介绍两种操作方式,一种是.NETFramework的ADO.NET《Ado.Net百科》,另一种就是NetCore2.0下的一种orm操作EFCore,由于本人习惯Ado.Net编程模式,EFCore涉... 查看详情
asp.netcore2.0项目实战ncmvc一个基于netcore2.0搭建的角色权限管理开发框架(代码片段)
....总结 1. 摘要 NCMVC角色权限管理框架是由最近练习NetCore时抽时间整理的系统,后续能不能发展成一个cms还要看朋友们是否有需要或时间是否充实。这里NCMVC主要还是给想要学习接触Asp.NetCore2.0的朋友们提供一些借鉴以及坑... 查看详情
adminlte
0Asp.NetCore项目实战之权限管理系统(0)无中生有1Asp.NetCore项目实战之权限管理系统(1)使用AdminLTE搭建前端2Asp.NetCore项目实战之权限管理系统(2)实体设计github源码地址0布局页、起始页及错误页0.0布局页使用布局页相当于一个... 查看详情
asp.netcore中间件详解及项目实战(代码片段)
原文:ASP.NETCore中间件详解及项目实战前言在上篇文章主要介绍了DotNetCore项目状况,本篇文章是我们在开发自己的项目中实际使用的,比较贴合实际应用,算是对中间件的一个深入使用了,不是简单的HelloWorld,如果你觉得本篇文... 查看详情
netcore体系-web应用程序-4asp.netcore2.0项目实战-13基于onactionexecuting全局过滤器,页面操作权限过滤控制到按钮级(代码片段)
...理 权限管理的基本定义:百度百科。 基于《Asp.NetCore2.0项目实战(10)基于cookie登录授权认证并实现前台会员、后台管理员同时登录》我们做过了登录认证,登录是权限的最基础的认证,没有登录就没有接下来的各种操... 查看详情
由asp.netcore根据路径下载文件异常引发的探究
...项目中存在文件下载功能,没有使用类似MinIO或OSS之类的分布式文件系统,而是下载本地文件,也就是根据本地文件路径进行下载。这其中遇到了一个问题,是关于如何提供文件路径的,通过本文记录一下相关总结,希望能帮助... 查看详情
asp.netcore中的缓存[1]:如何在一个asp.netcore应用中使用缓存
...以选择将数据缓存在应用进程自身的内存中,还可以采用分布式的形式将缓存数据存储在一个“中心数据库”中。对于分布式缓存,.NETCore提供了针对Redis和SQLServer的原生支持。除了这个独立的缓存系统之外,ASP.NETCore还借... 查看详情
net开源项目整理
....应用nopcommerce,开源电商网站,开发环境asp.netmvc(未支持.netcore),使用技术(autofac,ef,页面插件等)https://github.com/nopSolutions/nopCommerceOrchardCMS,内容管理网站https://github.com/OrchardCMS/Orchard(.net版本)https://github.com/OrchardCMS/Orchard2(.n... 查看详情
由asp.netcore根据路径下载文件异常引发的探究(代码片段)
...中存在文件下载功能,没有使用类似MinIO或OSS之类的分布式文件系统,而是下载本地文件,也就是根据本地文件路径进行下载。这其中遇到了一个问题,是关于如何提供文件路径的,通过本文记录一下相关总结... 查看详情