跟我一起学.NetCore之熟悉的接口权限验证不能少(Jwt) (2)

以上案例演示中,在登录的时候模拟权限数据存入内存,对于一些用户数据不大的项目,这种方式还不错,但是对于用户数量比较大或者分布式部署的项目,建议将权限数据存入Redis等缓存数据库中,存取统一的同时也能减少对数据库的访问压力,总不能每次请求过来都从数据库中获取权限数据进行校验。

小知识点:

通过获取用户时,访问的接口必须要有Authorize特性,否则只能通过自己解析Token获取;

如果在统一受保护的控制器中,有个别接口不需要权限验证,可以为其标注AllowAnonymous特性即可;

校验权限逻辑的完整代码如下:

using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace SwaggerDemo.Permission { /// <summary> /// 权限处理的关键类 /// </summary> public class PermissionHandler : AuthorizationHandler<PermissionRequirement> { /// <summary> /// 通过IHttpContextAccessor可以获取HttpContext相关信息,但一定要注册服务 /// </summary> private readonly IHttpContextAccessor _accessor; /// <summary> /// 用于判断请求是否带有凭据和是否登录 /// </summary> public IAuthenticationSchemeProvider Scheme { get; set; } /// <summary> /// 构造函数注入 /// </summary> public PermissionHandler(IHttpContextAccessor accessor,IAuthenticationSchemeProvider scheme) { this._accessor = accessor; Scheme = scheme; } protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement) { try { //拿到HttpContext就无所不能啦 var httpContext = _accessor.HttpContext; //判断资源数据中权限列表中是否有权限 if (!requirement.Permissions.Any()) { //没有直接返回无权限,也可以重新获取权限,实现不退出重新登录就可获取最新权限 context.Fail(); } //判读请求是否拥有凭据,即是否登录 var defaultAuthenticate = await Scheme.GetDefaultAuthenticateSchemeAsync(); if (defaultAuthenticate == null) { context.Fail(); } var result = await httpContext.AuthenticateAsync(defaultAuthenticate.Name); //不为空代表登录成功,为空登录失败 if (result?.Principal != null) { // 获取生成Token时放在payload里的userId string userId = _accessor.HttpContext.User.FindFirst("userId").Value; // 获取当前请求的地址 string requestUrl = httpContext.Request.Path.Value.ToLower(); // 从权限表中查找当前用户是否有当前请求地址的权限 var permission = requirement.Permissions.FirstOrDefault(a => a.Url.ToLower() == requestUrl && a.UserId == userId); // 如果没找到,代表没有权限 if (permission == null) { context.Fail(); } // 如果找到,就继续往下执行 context.Succeed(requirement); } else { // 获取不到对应值就返回无权限 context.Fail(); } } catch (Exception ex) { context.Fail(); } } } }

总结

关于权限验证这块之前大多都是在MVC的授权过滤器中进行完成的, 本来想在说过滤器那块一起说说权限验证的,但感觉关于Jwt的放在一块比较合适。关于Jwt其实还有一个比较关键的点,就是对于Token的处理问题,比如刷新Token、手动失效Token等,这块后续单独整理一篇内容分享。下次先说说过滤器的执行顺序。

关于代码,其实现在在写案例的时候感觉已经开始复杂了,后面整理整理会放在github上,如果急需的可以私下找我,我单独发给小伙伴。

一个被程序搞丑的帅小伙,关注"Code综艺圈",识别关注跟我一起学~~~

跟我一起学.NetCore之熟悉的接口权限验证不能少(Jwt)

撸文不易,莫要白瞟,三连走起~~~~

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpszgd.html