.NET Core授权失败如何自定义响应信息?
【導讀】在.NET 5之前,當授權失敗即403時無法很友好的自定義錯誤信息,以致于比如利用Vue獲取到的是空響應,不能很好的處理實際業務,同時涉及到權限粒度控制到控制器、Action,也不能很好的獲取對應路由信息
本文我們來看看在.NET 5中為何要出現針對授權失敗的中間件接口?它是如何一步步衍生出來的呢?以及 對于授權失敗根據實際需要如何自定義響應錯誤,以及如何獲取對應路由信息等等
授權失敗自定義響應信息
如下是在.NET 5之前,對于授權處理,我們大多實現自定義的AuthorizationHandler
但此時參數給予的是授權上下文,我們并不能拿到當前請求上下文中的相關信息,如果是在mvc中,想必大多是如下這般獲取的
protected?override?Task?HandleRequirementAsync(AuthorizationHandlerContext?context,?CustomAuthorizationRequirement?requirement) {var?context?=?context.Resource?as?HttpContext; }但對于前后分離的web api中,若我沒記錯的話,這樣是獲取到的是空,于是乎我們借助于注入上下文接口實現,演變成如下這樣
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;//?授權失敗響應信息await?httpContext.Response.WriteAsync("授權失敗");//響應失敗調用context.Fail();} }
通過上下文可以拿到比如用戶聲明信息等等,貌似已經基本滿足我們實際業務需求,那要是我想獲取路由信息又該如何呢?在3.0以下貌似只能通過Path自己解析(個人猜測)
從.NET Core 3.0+上,官方開放針對上下文的擴展方法,提供給我們獲取路由節點元數據詳細信息
在該終結點類存在一個元數據屬性,該屬性為集合,該元數據包含任何你想要的東東
這里必須強調一下,我最喜愛.NET Core的一點是,很多時候我們會封裝類庫,并在類庫中使用到Web APi中相關的上下文一切信息等等,如果是以前.NET Framework怕是有點麻煩
比如如上在類庫中獲取上下文接口,如果你還是延續舊思想,查看vs智能提示你是否需要安裝包,你會發現在Web APi中版本和你安裝的版本是對應不上的,這可能是有問題的哈(具體細節我并未深入探究),但實際上我想安裝的是.NET 5
在.NET Core類庫中要實現.NET Core相關基礎框架信息,只需要在類庫項目文件中引入支持.NET Core應用程序包包即可,如此才和當前應用程序版本完全一致
??<ItemGroup><FrameworkReference?Include="Microsoft.AspNetCore.App"?/></ItemGroup>面向不同群體讀者,這里重點強調下,以免初學.NET Core童鞋路走偏了!話題扯遠了,比如如上述我們想要獲取到元數據中的控制器和action名稱,該元數據集合參數都是object,所以我們想要對應的信息,需要稍微清楚一點.NET Core基本流程處理所提供的各個對象
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;} }講到這里,實現對應抽象授權處理對象,基本上可滿足我們的需求,即使上述拿到上下文并響應,但是在接口響應上我們是獲取不到的,因為授權上下文,只提供Fail和Succeed方法,要是我們想根據業務失敗后直接響應呢?所以最大的問題出在:我們無法完全控制響應,以及自定義響應
這個時候,經過開發者在github上激烈的反饋,官方在.NET 5給出了,針對授權處理的中間件接口,上下文也已直接對外暴露
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\":\"您暫無足夠的權限執行該操作\"}}");return;}await?next(context);} }自從.NET 5提供給了我們授權中間件接口,一切又是那么得心應手!
總結
以上是生活随笔為你收集整理的.NET Core授权失败如何自定义响应信息?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: .net core 下使用StackEx
- 下一篇: Prometheus(一):Web服务环