前言

在.NET 5之前,当授权失败即403时无法很友好的自定义错误信息,以致于比如利用Vue获取到的是空响应,不能很好的处理实际业务,同时涉及到权限粒度控制到控制器、Action,也不能很好的获取对应路由信息。本文我们来看看在.NET 5中为何要出现针对授权失败的中间件接口?它是如何一步步衍生出来的呢?以及对于授权失败根据实际需要如何自定义响应错误,以及如何获取对应路由信息等等

授权失败自定义响应信息

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

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

但此时参数给予的是授权上下文,我们并不能拿到当前请求上下文中的相关信息,如果是在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有了IAuthorizationMiddlewareResultHandler授权中间件接口,一切又是那么得心应手!

.NET Core授权失败如何自定义响应信息?的更多相关文章

  1. Nginx挂载维护页或返回自定义响应信息

    在服务停机升级或者服务暂不可用时,往往希望能够返回给用户更为明确和友好的响应信息.可以通过修改nginx配置文件,达到返回自定义信息的效果.有如下几种配置方式: (1)Nginx接收到的所有请求,都返 ...

  2. Asp.Net Core 中IdentityServer4 授权中心之自定义授权模式

    一.前言 上一篇我分享了一篇关于 Asp.Net Core 中IdentityServer4 授权中心之应用实战 的文章,其中有不少博友给我提了问题,其中有一个博友问我的一个场景,我给他解答的还不够完 ...

  3. 微信小程序获取用户信息“授权失败”场景的处理

    很多的时候我们在处理小程序功能的时候需要用户获取用户信息,但是呢为了信息安全,用户不授权导致授权失败场景:但是小程序第二次不在启动授权信息弹层,为了用户体验,可以用以下方式处理: function i ...

  4. [Swift]注册并购买加入Apple开发者计划。提示: “你的支付授权失败。请核对你的信息并重试,或尝试其他支付方式。请联系你的银行”

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  5. 【转】ASP.NET Core WebAPI JWT Bearer 认证失败返回自定义数据 Json

    应用场景:当前我们给微信小程序提供服务接口,接口中使用了权限认证这一块,当我使用 JWT Bearer 进行接口权限认证的时候,返回的结果不是我们客户端想要的,其它我们想要给客户端返回统一的数据结构, ...

  6. 理解ASP.NET Core - 授权(Authorization)

    注:本文隶属于<理解ASP.NET Core>系列文章,请查看置顶博客或点击此处查看全文目录 之前,我们已经了解了ASP.NET Core中的身份认证,现在,我们来聊一下授权. 老规矩,示 ...

  7. .NET CORE 授权

    .NET CORE 授权 一.三种方式授权 不论使用NET CORE框架的何种授权都必须引入中间件,因为它实现了在管道中对当前请求的鉴权和授权的验证,在Startup中的Configure中首先加入鉴 ...

  8. 聊聊asp.net core 授权流程

    在上一篇 聊聊 asp.net core 认证和授权 中我们提到了认证和授权的基本概念,以及认证和授权的关系及他们之间的协同工作流程,在这篇文章中,我将通过分析asp.net core 3.1 授权流 ...

  9. 【微信小程序】用户首次进入小程序拒绝授权,如何再次调用授权页面,获取用户信息userInfo

    前言:微信小程序的app.js里面,最少有2个接口,一个wx.login:一个是wx.getUserInfo: 前者得到腾讯给我们的微信用户唯一的code,通过code获取openid,这个不需要用户 ...

随机推荐

  1. H5开发基础之像素、分辨率、DPI、PPI

    H5开发基础之像素.分辨率.DPI.PPI  html5  阅读约 4 分钟 ​2016-09-03于坝上草原 背景知识: 目前绝大部分显示器都是基于点阵的,通过一系列的小点排成一个大矩形,通过每个小 ...

  2. node.js module初步理解-(转载)

    在开发一个复杂的应用程序的时候,我们需要把各个功能拆分.封装到不同的文件,在需要的时候引用该文件.没人会写一个几万行代码的文件,这样在可读性.复用性和维护性上都很差,几乎所有的编程语言都有自己的模块组 ...

  3. Kubernetes集群搭建 ver1.20.5

    目录 部署方式 1. 基础环境准备 1.1 基础初始化 1.2 安装docker 2. 部署harbor及haproxy高可用反向代理 2.1 镜像加速配置 2.2 高可用master可配置 3. 初 ...

  4. 机器学习实战二:波士顿房价预测 Boston Housing

    波士顿房价预测 Boston housing 这是一个波士顿房价预测的一个实战,上一次的Titantic是生存预测,其实本质上是一个分类问题,就是根据数据分为1或为0,这次的波士顿房价预测更像是预测一 ...

  5. Gorm入门使用

    Gorm GORM CRUD 数据库的增删改查 go get -u github.com/jinzhu/gorm go get -u github.com/jinzhu/gorm/dialects/m ...

  6. Hadoop系列番外篇之一文搞懂Hadoop RPC框架及细节实现

    @ 目录 Hadoop RPC 框架解析 1.Hadoop RPC框架概述 1.1 RPC框架特点 1.2 Hadoop RPC框架 2.Java基础知识回顾 2.1 Java反射机制与动态代理 2. ...

  7. Navicat注册机报错No all pattern found! file already patched

    第一步:先把注册机放入安装目录. (这一步非常关键,先不要打开桌面上安装好的快捷方式!!) 第二步:如果之前下载过,把注册表清理干净 计算机\HKEY_CURRENT_USER\SOFTWARE\Pr ...

  8. 情景剧:C/C++中的未定义行为(undefined behavior)

    写在前面 本文尝试以情景剧的方式,轻松.直观地解释C/C++中未定义行为(undefined behavior)的概念.设计动机.优缺点等内容1,希望读者能够通过阅读本文,对undefined beh ...

  9. Angel图算法

    Angel图算法 [2.0]CommonFriends 计算两个好友的共同好友数,某种程度上可以刻画两个节点之间的紧密程度. 输入 输入数据路径:输入文件所在路径,无权网络数据, 数据格式为两列 sr ...

  10. GPU加速:宽深度推理

    GPU加速:宽深度推理 Accelerating Wide & Deep Recommender Inference on GPUs 推荐系统推动了许多最流行的在线平台的参与.随着为这些系统提 ...