<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          .NET Core授權(quán)失敗如何自定義響應(yīng)信息?

          共 4390字,需瀏覽 9分鐘

           ·

          2021-12-15 01:02

          【導(dǎo)讀】在.NET 5之前,當(dāng)授權(quán)失敗即403時(shí)無法很友好的自定義錯(cuò)誤信息,以致于比如利用Vue獲取到的是空響應(yīng),不能很好的處理實(shí)際業(yè)務(wù),同時(shí)涉及到權(quán)限粒度控制到控制器、Action,也不能很好的獲取對應(yīng)路由信息


          本文我們來看看在.NET 5中為何要出現(xiàn)針對授權(quán)失敗的中間件接口?它是如何一步步衍生出來的呢?以及 對于授權(quán)失敗根據(jù)實(shí)際需要如何自定義響應(yīng)錯(cuò)誤,以及如何獲取對應(yīng)路由信息等等


          授權(quán)失敗自定義響應(yīng)信息


          如下是在.NET 5之前,對于授權(quán)處理,我們大多實(shí)現(xiàn)自定義的AuthorizationHandler

          public?class?CustomAuthorizeHandler?:?AuthorizationHandler<CustomAuthorizationRequirement>
          {
          ????protected?override?Task?HandleRequirementAsync(AuthorizationHandlerContext?context,?CustomAuthorizationRequirement?requirement)
          ????{
          ????????throw?new?NotImplementedException();
          ????}
          }

          public?class?CustomAuthorizationRequirement?:?IAuthorizationRequirement
          {
          ????public?CustomAuthorizationRequirement()
          ????{
          ????}
          }


          但此時(shí)參數(shù)給予的是授權(quán)上下文,我們并不能拿到當(dāng)前請求上下文中的相關(guān)信息,如果是在mvc中,想必大多是如下這般獲取的

          protected?override?Task?HandleRequirementAsync(AuthorizationHandlerContext?context,?CustomAuthorizationRequirement?requirement)
          {
          ????var?context?=?context.Resource?as?HttpContext;
          }

          但對于前后分離的web api中,若我沒記錯(cuò)的話,這樣是獲取到的是空,于是乎我們借助于注入上下文接口實(shí)現(xiàn),演變成如下這樣

          public?class?CustomAuthorizeHandler?:?AuthorizationHandler<CustomAuthorizationRequirement>
          {
          ????private?readonly?IHttpContextAccessor?_accessor;
          ????public?CustomAuthorizeHandler(IHttpContextAccessor?accessor)
          ????{
          ????????_accessor?=?accessor;
          ????}
          ????protected?async?override?Task?HandleRequirementAsync(AuthorizationHandlerContext?context,?CustomAuthorizationRequirement?requirement)
          ????{
          ????????var?httpContext?=?_accessor.HttpContext;

          ????????//?授權(quán)失敗響應(yīng)信息
          ????????await?httpContext.Response.WriteAsync("授權(quán)失敗");

          ????????//響應(yīng)失敗調(diào)用
          ????????context.Fail();

          ????}
          }


          通過上下文可以拿到比如用戶聲明信息等等,貌似已經(jīng)基本滿足我們實(shí)際業(yè)務(wù)需求,那要是我想獲取路由信息又該如何呢?在3.0以下貌似只能通過Path自己解析(個(gè)人猜測)


          從.NET Core 3.0+上,官方開放針對上下文的擴(kuò)展方法,提供給我們獲取路由節(jié)點(diǎn)元數(shù)據(jù)詳細(xì)信息

          在該終結(jié)點(diǎn)類存在一個(gè)元數(shù)據(jù)屬性,該屬性為集合,該元數(shù)據(jù)包含任何你想要的東東


          這里必須強(qiáng)調(diào)一下,我最喜愛.NET Core的一點(diǎn)是,很多時(shí)候我們會封裝類庫,并在類庫中使用到Web APi中相關(guān)的上下文一切信息等等,如果是以前.NET Framework怕是有點(diǎn)麻煩


          比如如上在類庫中獲取上下文接口,如果你還是延續(xù)舊思想,查看vs智能提示你是否需要安裝包,你會發(fā)現(xiàn)在Web APi中版本和你安裝的版本是對應(yīng)不上的,這可能是有問題的哈(具體細(xì)節(jié)我并未深入探究),但實(shí)際上我想安裝的是.NET 5


          在.NET Core類庫中要實(shí)現(xiàn).NET Core相關(guān)基礎(chǔ)框架信息,只需要在類庫項(xiàng)目文件中引入支持.NET Core應(yīng)用程序包包即可,如此才和當(dāng)前應(yīng)用程序版本完全一致

          ??
          ????"Microsoft.AspNetCore.App"?/>
          ??


          面向不同群體讀者,這里重點(diǎn)強(qiáng)調(diào)下,以免初學(xué).NET Core童鞋路走偏了!話題扯遠(yuǎn)了,比如如上述我們想要獲取到元數(shù)據(jù)中的控制器和action名稱,該元數(shù)據(jù)集合參數(shù)都是object,所以我們想要對應(yīng)的信息,需要稍微清楚一點(diǎn).NET Core基本流程處理所提供的各個(gè)對象

          public?class?CustomAuthorizeHandler?:?AuthorizationHandler<CustomAuthorizationRequirement>
          {
          ????private?readonly?IHttpContextAccessor?_accessor;
          ????public?CustomAuthorizeHandler(IHttpContextAccessor?accessor)
          ????{
          ????????_accessor?=?accessor;
          ????}
          ????protected?async?override?Task?HandleRequirementAsync(AuthorizationHandlerContext?context,?CustomAuthorizationRequirement?requirement)
          ????{
          ????????var?httpContext?=?_accessor.HttpContext;

          ????????var?endPoint?=?httpContext.GetEndpoint();

          ????????var?controllerActionDescriptor?=?(ControllerActionDescriptor)endPoint.Metadata
          ????????????.ToList().FirstOrDefault(d?=>?d?is?ControllerActionDescriptor);

          ????????var?controllerName?=?controllerActionDescriptor.ControllerName;

          ????????var?actionName?=?controllerActionDescriptor.ActionName;

          ????}
          }


          講到這里,實(shí)現(xiàn)對應(yīng)抽象授權(quán)處理對象,基本上可滿足我們的需求,即使上述拿到上下文并響應(yīng),但是在接口響應(yīng)上我們是獲取不到的,因?yàn)槭跈?quán)上下文,只提供Fail和Succeed方法,要是我們想根據(jù)業(yè)務(wù)失敗后直接響應(yīng)呢?所以最大的問題出在:我們無法完全控制響應(yīng),以及自定義響應(yīng)


          這個(gè)時(shí)候,經(jīng)過開發(fā)者在github上激烈的反饋,官方在.NET 5給出了,針對授權(quán)處理的中間件接口,上下文也已直接對外暴露

          public?class?CustomAuthorizationMiddlewareResultHandler
          ????????:?IAuthorizationMiddlewareResultHandler
          {

          ????public?async?Task?HandleAsync(RequestDelegate?next,
          ??????HttpContext?context,?AuthorizationPolicy?policy,?PolicyAuthorizationResult?authorizeResult
          )

          ????{
          ????????var?endPoint?=?context.GetEndpoint();

          ????????var?controllerActionDescriptor?=?(ControllerActionDescriptor)endPoint.Metadata
          ??????????.ToList().FirstOrDefault(d?=>?d?is?ControllerActionDescriptor);

          ????????var?controllerName?=?controllerActionDescriptor.ControllerName;

          ????????var?actionName?=?controllerActionDescriptor.ActionName;

          ????????if?(!context.User.Identity.IsAuthenticated)
          ????????{
          ????????????context.Response.StatusCode?=?(int)HttpStatusCode.Unauthorized;
          ????????????await?context.Response.WriteAsync("{\"data\":{\"succeeded\":false,\"code\":401,\"message\":\"登錄已過期,請重新登錄\"}}");
          ????????????return;
          ????????}
          ????????else?if?(!await?HandleRequirementEvaluateAsync(context.User,?controllerName,?actionName))
          ????????{
          ????????????context.Response.StatusCode?=?(int)HttpStatusCode.Forbidden;
          ????????????await?context.Response.WriteAsync("{\"data\":{\"succeeded\":false,\"code\":403,\"message\":\"您暫無足夠的權(quán)限執(zhí)行該操作\"}}");
          ????????????return;
          ????????}
          ????????await?next(context);
          ????}
          }


          自從.NET 5提供給了我們授權(quán)中間件接口,一切又是那么得心應(yīng)手!

          瀏覽 43
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧洲三级片视频 | 欧美成人色图 | 成人AV电影网 久久爱 | 一区二区三区四区免费 | 无码操逼动漫 |