.NETCore授权失败如何自定义响应信息?

本文转载自微信公众号「JeffckyShare」,作者Jeffcky。转载本文请联系JeffckyShare公众号。

成都创新互联是一家集网站建设,仁布企业网站建设,仁布品牌网站建设,网站定制,仁布网站建设报价,网络营销,网络优化,仁布网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。

本文我们来看看在.NET 5中为何要出现针对授权失败的中间件接口?它是如何一步步衍生出来的呢?以及 对于授权失败根据实际需要如何自定义响应错误,以及如何获取对应路由信息等等

授权失败自定义响应信息

如下是在.NET 5之前,对于授权处理,我们大多实现自定义的AuthorizationHandler

 
 
 
 
  1. public class CustomAuthorizeHandler : AuthorizationHandler 
  2.     protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CustomAuthorizationRequirement requirement) 
  3.     { 
  4.         throw new NotImplementedException(); 
  5.     } 
  6.  
  7. public class CustomAuthorizationRequirement : IAuthorizationRequirement 
  8.     public CustomAuthorizationRequirement() 
  9.     { 
  10.     } 

但此时参数给予的是授权上下文,我们并不能拿到当前请求上下文中的相关信息,如果是在mvc中,想必大多是如下这般获取的

 
 
 
 
  1. protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CustomAuthorizationRequirement requirement) 
  2.     var context = context.Resource as HttpContext; 

但对于前后分离的web api中,若我没记错的话,这样是获取到的是空,于是乎我们借助于注入上下文接口实现,演变成如下这样

 
 
 
 
  1. public class CustomAuthorizeHandler : AuthorizationHandler 
  2.     private readonly IHttpContextAccessor _accessor; 
  3.     public CustomAuthorizeHandler(IHttpContextAccessor accessor) 
  4.     { 
  5.         _accessor = accessor; 
  6.     } 
  7.     protected async override Task HandleRequirementAsync(AuthorizationHandlerContext context, CustomAuthorizationRequirement requirement) 
  8.     { 
  9.         var httpContext = _accessor.HttpContext; 
  10.  
  11.         // 授权失败响应信息 
  12.         await httpContext.Response.WriteAsync("授权失败"); 
  13.  
  14.         //响应失败调用 
  15.         context.Fail(); 
  16.  
  17.     } 

通过上下文可以拿到比如用户声明信息等等,貌似已经基本满足我们实际业务需求,那要是我想获取路由信息又该如何呢?在3.0以下貌似只能通过Path自己解析(个人猜测)

从.NET Core 3.0+上,官方开放针对上下文的扩展方法,提供给我们获取路由节点元数据详细信息

在该终结点类存在一个元数据属性,该属性为集合,该元数据包含任何你想要的东东

这里必须强调一下,我最喜爱.NET Core的一点是,很多时候我们会封装类库,并在类库中使用到Web APi中相关的上下文一切信息等等,如果是以前.NET Framework怕是有点麻烦

比如如上在类库中获取上下文接口,如果你还是延续旧思想,查看vs智能提示你是否需要安装包,你会发现在Web APi中版本和你安装的版本是对应不上的,这可能是有问题的哈(具体细节我并未深入探究),但实际上我想安装的是.NET 5

在.NET Core类库中要实现.NET Core相关基础框架信息,只需要在类库项目文件中引入支持.NET Core应用程序包包即可,如此才和当前应用程序版本完全一致

 
 
 
 
  1.  
  2.     
  3.   

面向不同群体读者,这里重点强调下,以免初学.NET Core童鞋路走偏了!话题扯远了,比如如上述我们想要获取到元数据中的控制器和action名称,该元数据集合参数都是object,所以我们想要对应的信息,需要稍微清楚一点.NET Core基本流程处理所提供的各个对象

 
 
 
 
  1. public class CustomAuthorizeHandler : AuthorizationHandler 
  2.     private readonly IHttpContextAccessor _accessor; 
  3.     public CustomAuthorizeHandler(IHttpContextAccessor accessor) 
  4.     { 
  5.         _accessor = accessor; 
  6.     } 
  7.     protected async override Task HandleRequirementAsync(AuthorizationHandlerContext context, CustomAuthorizationRequirement requirement) 
  8.     { 
  9.         var httpContext = _accessor.HttpContext; 
  10.  
  11.         var endPoint = httpContext.GetEndpoint(); 
  12.  
  13.         var controllerActionDescriptor = (ControllerActionDescriptor)endPoint.Metadata 
  14.             .ToList().FirstOrDefault(d => d is ControllerActionDescriptor); 
  15.  
  16.         var controllerName = controllerActionDescriptor.ControllerName; 
  17.  
  18.         var actionName = controllerActionDescriptor.ActionName; 
  19.  
  20.     } 

讲到这里,实现对应抽象授权处理对象,基本上可满足我们的需求,即使上述拿到上下文并响应,但是在接口响应上我们是获取不到的,因为授权上下文,只提供Fail和Succeed方法,要是我们想根据业务失败后直接响应呢?所以最大的问题出在:我们无法完全控制响应,以及自定义响应

这个时候,经过开发者在github上激烈的反馈,官方在.NET 5给出了,针对授权处理的中间件接口,上下文也已直接对外暴露

 
 
 
 
  1. public class CustomAuthorizationMiddlewareResultHandler 
  2.         : IAuthorizationMiddlewareResultHandler 
  3.  
  4.     public async Task HandleAsync(RequestDelegate next, 
  5.       HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult) 
  6.     { 
  7.         var endPoint = context.GetEndpoint(); 
  8.  
  9.         var controllerActionDescriptor = (ControllerActionDescriptor)endPoint.Metadata 
  10.           .ToList().FirstOrDefault(d => d is ControllerActionDescriptor); 
  11.  
  12.         var controllerName = controllerActionDescriptor.ControllerName; 
  13.  
  14.         var actionName = controllerActionDescriptor.ActionName; 
  15.  
  16.         if (!context.User.Identity.IsAuthenticated) 
  17.         { 
  18.             context.Response.StatusCode = (int)HttpStatusCode.Unauthorized; 
  19.             await context.Response.WriteAsync("{\"data\":{\"succeeded\":false,\"code\":401,\"message\":\"登录已过期,请重新登录\"}}"); 
  20.             return; 
  21.         } 
  22.         else if (!await HandleRequirementEvaluateAsync(context.User, controllerName, actionName)) 
  23.         { 
  24.             context.Response.StatusCode = (int)HttpStatusCode.Forbidden; 
  25.             await context.Response.WriteAsync("{\"data\":{\"succeeded\":false,\"code\":403,\"message\":\"您暂无足够的权限执行该操作\"}}"); 
  26.             return; 
  27.         } 
  28.         await next(context); 
  29.     } 

自从.NET 5提供给了我们授权中间件接口,一切又是那么得心应手!

分享标题:.NETCore授权失败如何自定义响应信息?
网页链接:http://www.gawzjz.com/qtweb2/news24/21224.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联