.NET Core授權(quán)失敗自定義響應(yīng)信息的操作方法
前言
在.NET 5之前,當授權(quán)失敗即403時無法很友好的自定義錯誤信息,以致于比如利用Vue獲取到的是空響應(yīng),不能很好的處理實際業(yè)務(wù),同時涉及到權(quán)限粒度控制到控制器、Action,也不能很好的獲取對應(yīng)路由信息。本文我們來看看在.NET 5中為何要出現(xiàn)針對授權(quán)失敗的中間件接口?它是如何一步步衍生出來的呢?以及對于授權(quán)失敗根據(jù)實際需要如何自定義響應(yīng)錯誤,以及如何獲取對應(yīng)路由信息等等
授權(quán)失敗自定義響應(yīng)信息
如下是在.NET 5之前,對于授權(quán)處理,我們大多實現(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ù)給予的是授權(quán)上下文,我們并不能拿到當前請求上下文中的相關(guān)信息,如果是在mvc中,想必大多是如下這般獲取的
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CustomAuthorizationRequirement requirement) { var context = context.Resource as HttpContext; }
但對于前后分離的web api中,若我沒記錯的話,這樣是獲取到的是空,于是乎我們借助于注入上下文接口實現(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)基本滿足我們實際業(yè)務(wù)需求,那要是我想獲取路由信息又該如何呢?在3.0以下貌似只能通過Path自己解析(個人猜測),從.NET Core 3.0+上,官方開放針對上下文的擴展方法,提供給我們獲取路由節(jié)點元數(shù)據(jù)詳細信息
在該終結(jié)點類存在一個元數(shù)據(jù)屬性,該屬性為集合,該元數(shù)據(jù)包含任何你想要的東東
這里必須強調(diào)一下,我最喜愛.NET Core的一點是,很多時候我們會封裝類庫,并在類庫中使用到Web APi中相關(guān)的上下文一切信息等等,如果是以前.NET Framework怕是有點麻煩
比如如上在類庫中獲取上下文接口,如果你還是延續(xù)舊思想,查看vs智能提示你是否需要安裝包,你會發(fā)現(xiàn)在Web APi中版本和你安裝的版本是對應(yīng)不上的,這可能是有問題的哈(具體細節(jié)我并未深入探究),但實際上我想安裝的是.NET 5
在.NET Core類庫中要實現(xiàn).NET Core相關(guān)基礎(chǔ)框架信息,只需要在類庫項目文件中引入支持.NET Core應(yīng)用程序包包即可,如此才和當前應(yīng)用程序版本完全一致
<ItemGroup> <FrameworkReference Include="Microsoft.AspNetCore.App" /> </ItemGroup>
面向不同群體讀者,這里還是重點強調(diào)下,以免有些學(xué)習(xí).NET Core的童鞋走偏了!話題扯遠了,比如如上述我們想要獲取到元數(shù)據(jù)中的控制器和action名稱,該元數(shù)據(jù)集合參數(shù)都是object,所以我們想要對應(yīng)的信息,需要稍微清楚一點.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; } }
講到這里,實現(xiàn)對應(yīng)抽象授權(quán)處理對象,基本上可滿足我們的需求,即使上述拿到上下文并響應(yīng),但是在接口響應(yīng)上我們是獲取不到的,因為授權(quán)上下文,只提供Fail和Succeed方法,要是我們想根據(jù)業(yè)務(wù)失敗后直接響應(yīng)呢?所以最大的問題出在:我們無法完全控制響應(yīng),以及自定義響應(yīng)。這個時候,經(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有了IAuthorizationMiddlewareResultHandler授權(quán)中間件接口,一切又是那么得心應(yīng)手!
到此這篇關(guān)于.NET Core授權(quán)失敗如何自定義響應(yīng)信息的文章就介紹到這了,更多相關(guān).NET Core自定義響應(yīng)信息內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
代碼實現(xiàn)打印功能(asp.net+javascript)
頁面實現(xiàn)打印的效果代碼,分為服務(wù)器端和客戶端單個即可,客戶端的比較不錯,本站也是類似的方法。2009-05-05asp.net MVC利用自定義ModelBinder過濾關(guān)鍵字的方法(附demo源碼下載)
這篇文章主要介紹了MVC利用自定義ModelBinder過濾關(guān)鍵字的方法,結(jié)合實例形式詳細分析了自定義ModelBinder過濾關(guān)鍵字的原理與具體實現(xiàn)技巧,需要的朋友可以參考下2016-03-03ASP.NET Core自動生成小寫破折號路由的實現(xiàn)方法
這篇文章主要介紹了ASP.NET Core自動生成小寫破折號路由的實現(xiàn)方法,幫助大家更好的理解和學(xué)習(xí)使用ASP.NET Core,感興趣的朋友可以了解下2021-04-04合并網(wǎng)頁中的多個script引用實現(xiàn)思路及代碼
為了更好的進行封裝,每個實現(xiàn)不同功能的js代碼應(yīng)該有自己的js文件,這樣如果一個網(wǎng)頁中引用了多個js文件會很難管理,所以就出現(xiàn)了合并js這以說,感興趣的朋友不妨參考下本文希望對你有所幫助2013-02-02