ASP.NET Core下自定义授权返回结果
2021/8/21 9:06:35
本文主要是介绍ASP.NET Core下自定义授权返回结果,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
今天在为项目编写API统一返回结果的代码时,发现不能通过Filter来定义授权失败后的响应结果,于是我翻看了一下官方文档和aspnetcore源码,原来需要自定义实现IAuthorizationMiddlewareResultHandler接口。
Asp.Net Core 5自带的验权中间件,在验权失败后,是直接返回一个401。这对于前端来说不太友好,所以我的需求是改为返回200的自定义结果。
我通过搜索引擎查阅了一下别人实现的代码,发现都比较复杂,我这里需求比较简单,就不做太复杂的判断。
环境:ASP.NET Core 5。
一、首先定义AuthorizationMiddlewareResultHandler类,并且实现IAuthorizationMiddlewareResultHandler接口。
1 using Microsoft.AspNetCore.Authorization; 2 using Microsoft.AspNetCore.Authorization.Policy; 3 using Microsoft.AspNetCore.Http; 4 using System.Threading.Tasks; 5 6 namespace DotNet.AspNetCore.WebApi 7 { 8 public class AuthorizationMiddlewareResultHandler : IAuthorizationMiddlewareResultHandler 9 { 10 public async Task HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult) 11 { 12 //因为管道还没有走到Action 所以没有ActionResult使用 我们必须自己定义Response中的内容 13 //这里授权是否成功 14 if (!authorizeResult.Succeeded) 15 { 16 //将状态码定义为200 17 context.Response.StatusCode = 200; 18 //使用 WriteAsJsonAsync 写入一个自定义的返回对象 自动完成Json的序列化操作 19 //我这里用匿名类演示 实际项目中请替换成对应的返回对象 自定义状态码和提示信息 20 await context.Response.WriteAsJsonAsync(new { Code = 401, Message = "没有权限", Result = string.Empty }); 21 //注意一定要return 在这里短路管道 不要走到next 否则线程会进入后续管道 到达action中 22 return; 23 } 24 //如果授权成功 继续执行后续的中间件 记住一定记得next 否则会管道会短路 25 await next(context); 26 } 27 } 28 }
二、在Startup.cs中注入单例服务,将其作为IAuthorizationMiddlewareResultHandler的实现。
1 public void ConfigureServices(IServiceCollection services) 2 { // IAuthorizationMiddlewareResultHandler 用来替换框架默认的授权返回结果 4 services.AddSingleton<IAuthorizationMiddlewareResultHandler, AuthorizationMiddlewareResultHandler>(); }
代码非常简单,很容易就自定义了授权返回结果。但是,到这里就结束了吗?不不不,好奇的我想知道为什么要这样写,于是我去看了一下源码。
在查看了app.UseAuthentication()对应的AuthorizationMiddleware中间件后,发现在Invoke的最后有这么一段代码:
var authorizeResult = await policyEvaluator.AuthorizeAsync(policy, authenticateResult!, context, resource); var authorizationMiddlewareResultHandler = context.RequestServices.GetRequiredService<IAuthorizationMiddlewareResultHandler>(); await authorizationMiddlewareResultHandler.HandleAsync(_next, context, policy, authorizeResult);
context.RequestServices.GetRequiredService<IAuthorizationMiddlewareResultHandler>()这段代码表明,AuthorizationMiddleware中间件是通过获取服务容器中IAuthorizationMiddlewareResultHandler的实例,来处理授权返回结果。而我们上面的AddSingleton<IAuthorizationMiddlewareResultHandler, AuthorizationMiddlewareResultHandler>()则是替换掉了框架中原有的默认实现,从而达到了我们想要的返回结果。
啧啧啧,又学会了一招如何巧妙的设计中间件。
这里我把框架原有的实现也贴出来:
1 public class AuthorizationMiddlewareResultHandler : IAuthorizationMiddlewareResultHandler 2 { 3 /// <inheritdoc /> 4 public async Task HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult) 5 { 6 if (authorizeResult.Challenged) 7 { 8 if (policy.AuthenticationSchemes.Count > 0) 9 { 10 foreach (var scheme in policy.AuthenticationSchemes) 11 { 12 await context.ChallengeAsync(scheme); 13 } 14 } 15 else 16 { 17 await context.ChallengeAsync(); 18 } 19 20 return; 21 } 22 else if (authorizeResult.Forbidden) 23 { 24 if (policy.AuthenticationSchemes.Count > 0) 25 { 26 foreach (var scheme in policy.AuthenticationSchemes) 27 { 28 await context.ForbidAsync(scheme); 29 } 30 } 31 else 32 { 33 await context.ForbidAsync(); 34 } 35 36 return; 37 } 38 39 await next(context); 40 } 41 }
看来还是要经常回顾一下以前的知识,持之以恒,夯实基础。
author:https://www.cnblogs.com/abnerwong/
这篇关于ASP.NET Core下自定义授权返回结果的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2022-03-01沐雪多租宝商城源码从.NetCore3.1升级到.Net6的步骤
- 2024-11-15C#中怎么从PEM格式的证书中提取公钥?-icode9专业技术文章分享
- 2024-11-14云架构设计——如何用diagrams.net绘制专业的AWS架构图?
- 2024-05-08首个适配Visual Studio平台的国产智能编程助手CodeGeeX正式上线!C#程序员必备效率神器!
- 2024-03-30C#设计模式之十六迭代器模式(Iterator Pattern)【行为型】
- 2024-03-29c# datetime tryparse
- 2024-02-21list find index c#
- 2024-01-24convert toint32 c#
- 2024-01-24Advanced .Net Debugging 1:你必须知道的调试工具
- 2024-01-24.NET集成IdGenerator生成分布式全局唯一ID