天津seo优化公司,培训机构seo,广州企业网站找哪里,好用的网站建设工具哈喽大家好#xff0c;这篇文章其实很早就想写了#xff0c;因为一直会有小伙伴问到#xff0c;但是我却始终拿不到好的方案#xff0c;最近在录制《eShopOnContainer微服务架构》的视频#xff0c;碰巧就看到了微软官方的代码中也有这方面的需求#xff0c;而且和我的需… 哈喽大家好这篇文章其实很早就想写了因为一直会有小伙伴问到但是我却始终拿不到好的方案最近在录制《eShopOnContainer微服务架构》的视频碰巧就看到了微软官方的代码中也有这方面的需求而且和我的需求不谋而合那我就抄一下吧当然要适当的做些修改可见还是要多学习一些框架的。预告从这周开始BCVP开发者组正式推广因为我先写了这篇文章所以我会在本周三的时候推广第一个项目感兴趣的还是要来哟《BCVP想真正为社区做努力的开发者们》。先说下问题吧我们平时在开发ASP.NETCore的WebApi的时候肯定会有权限相关的内容特别是在开发的阶段需要用到联合调试或者就是模拟测试那要获取真实的数据就需要去登录我们虽然有Swagger界面为我们省去了打开前端项目的麻烦但是Swagger也有自身的一些问题1、比如登录我们需要设置时间万一半个小时有效期内没有成功我们还得退出并重新登录一次2、Swagger采用的是Js赋值那我们刷新了以后这个Token就不见了我们又得重新点击登录然后输入到窗口内3、特别是在调试Ids4项目的时候还需要把Ids4认证平台的项目也打开一起运行才能实现效果。可以看到为了简单的调试一个业务的接口还是很麻烦的那我想着有没有一个方案可以一次配置长久有效呢肯定是有的而且很简单只需要简单的设计一个中间件就能轻松搞定来吧内容很简单我就不多解释了直接1234上步骤。1、设计权限通过中间件这个内容还是比较清晰的我先直接写下代码 /// summary/// 测试用户用来通过鉴权/// JWT?userid8rolenameAdminTest/// /summarypublic class ByPassAuthMidd{private readonly RequestDelegate _next;// 定义变量当前用户Id会常驻内存。private string _currentUserId;// 同理定义当前角色名private string _currentRoleName;public ByPassAuthMidd(RequestDelegate next){_next next;_currentUserId null;_currentRoleName null;}public async Task Invoke(HttpContext context){var path context.Request.Path;// 请求地址通过Url参数的形式设置用户id和rolenameif (path /noauth){var userid context.Request.Query[userid];if (!string.IsNullOrEmpty(userid)){_currentUserId userid;}var rolename context.Request.Query[rolename];if (!string.IsNullOrEmpty(rolename)){_currentRoleName rolename;}await SendOkResponse(context, $User set to {_currentUserId} and Role set to {_currentRoleName}.);}// 重置角色信息else if (path /noauth/reset){_currentUserId null;_currentRoleName null;await SendOkResponse(context, $User set to none. Token required for protected endpoints.);}else{var currentUserId _currentUserId;var currentRoleName _currentRoleName;// 你也可以通过Header的形式。//var authHeader context.Request.Headers[Authorization];//if (authHeader ! StringValues.Empty)//{// var header authHeader.FirstOrDefault();// if (!string.IsNullOrEmpty(header) header.StartsWith(User ) header.Length User .Length)// {// currentUserId header.Substring(User .Length);// }//}// 如果用户id和rolename都不为空// 可以配置HttpContext.User信息了也就相当于登录了。if (!string.IsNullOrEmpty(currentUserId) !string.IsNullOrEmpty(currentRoleName)){var user new ClaimsIdentity(new[] {// 用户id new Claim(sub, currentUserId),// 用户名、角色名new Claim(name, Test user),new Claim(ClaimTypes.Name, Test user),new Claim(role, currentRoleName),new Claim(ClaimTypes.Role, currentRoleName),// 过期时间两个jwt/ids4new Claim (exp,${new DateTimeOffset(DateTime.Now.AddDays(10100)).ToUnixTimeSeconds()}),new Claim(ClaimTypes.Expiration, DateTime.Now.AddDays(1).ToString()),// 其他参数new Claim(nonce, Guid.NewGuid().ToString()),new Claim(http://schemas.microsoft.com/identity/claims/identityprovider, ByPassAuthMiddleware),new Claim(http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname,User),new Claim(http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname,Microsoft)}, ByPassAuth);context.User new ClaimsPrincipal(user);}await _next.Invoke(context);}}/// summary/// 返回相应/// /summary/// param namecontext/param/// param namemessage/param/// returns/returnsprivate async Task SendOkResponse(HttpContext context, string message){context.Response.StatusCode (int)System.Net.HttpStatusCode.OK;context.Response.ContentType text/plain;await context.Response.WriteAsync(message);}}
相应的注释我已经添加进去了参数可以任意增加过期时间任意配置就行可能第一次看的时候比较不是很清晰我下边会介绍如何使用你就会明白了。设计好中间件就需要配置下调用在Startup中配置中间件 // 测试用户用来通过鉴权if (Configuration.GetValuebool(AppSettings:UseLoadTest)){app.UseMiddlewareByPassAuthMidd();}// 先开启认证app.UseAuthentication();// 然后是授权中间件app.UseAuthorization();注意顺序一定要是认证和授权中间件的上边只需要简单想一想就能明白了先提供登录再进行权限判断嘛。其他的修改1、需要配置参数这个是肯定的就是上边的AppSettings:UseLoadTest在appsettings.json中配置特别注意的是在生产环境一定要去掉或者是禁用不然被人发现了得不偿失。2、修改自定义策略处理器因为我们已经是这种模拟登录了就不需要将Header中的令牌给转到Httpcontext上下文了已经是存在了的那就需要简单的修改下PermissionHandler.cs:主要就是这两点一个是登录判断增加了一个||的验证是否是测试环境还有一个就是不用result.Principal赋值了因为这里是空的。剩下的就没有什么了咱们来操作看看。2、测试效果首先、开启中间件服务就是在配置文件中设置为trueUseLoadTest: true
这个时候你可以测试下加权的接口肯定是由401的{status: 401,success: false,msg: 很抱歉您无权访问该接口请确保已经登录!
}
其次、配置用户信息上边已经有了那个路由了就是/noauth剩下的就是传递一个参数我的BlogCore中需要用到一个userid一个rolename所以直接传递过去http://localhost:8081/noauth?userid8rolenameAdminTest
这个参数由你的真实数据决定也可以做调整结果就是这样的User set to 8 and Role set to AdminTest.
最后、发起接口测试直接发送请求已经可以看到效果了是不是很方便我们也可以很随意的修改过期时间无论你怎么刷新页面数据都不会丢有时候你忘了赋值的是什么用户和角色了直接访问如果说想重置就直接访问接口这个时候又开始走我们的策略授权方案了是不是很简单合理使用中间件能帮助我们处理很多的麻烦就这样啦打完收工