.NET Core授权失败自定义响应信息的操作方法

 更新时间:2021年9月22日 09:59  点击:1716

前言

在.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授权失败如何自定义响应信息的文章就介绍到这了,更多相关.NET Core自定义响应信息内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!

[!--infotagslink--]

相关文章

  • ASP.NET购物车实现过程详解

    这篇文章主要为大家详细介绍了ASP.NET购物车的实现过程,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-22
  • .NET Core下使用Kafka的方法步骤

    这篇文章主要介绍了.NET Core下使用Kafka的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-09-22
  • C#创建自定义控件及添加自定义属性和事件使用实例详解

    这篇文章主要给大家介绍了关于C#创建自定义控件及添加自定义属性和事件使用的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用C#具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧...2020-06-25
  • 在ASP.NET 2.0中操作数据之七十二:调试存储过程

    在开发过程中,使用Visual Studio的断点调试功能可以很方便帮我们调试发现程序存在的错误,同样Visual Studio也支持对SQL Server里面的存储过程进行调试,下面就让我们看看具体的调试方法。...2021-09-22
  • JS实现自定义简单网页软键盘效果代码

    本文实例讲述了JS实现自定义简单网页软键盘效果。分享给大家供大家参考,具体如下:这是一款自定义的简单点的网页软键盘,没有使用任何控件,仅是为了练习JavaScript编写水平,安全性方面没有过多考虑,有顾虑的可以不用,目的是学...2015-11-08
  • Win10 IIS 安装.net 4.5的方法

    这篇文章主要介绍了Win10 IIS 安装及.net 4.5及Win10安装IIS并配置ASP.NET 4.0的方法,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下...2021-09-22
  • android自定义动态设置Button样式【很常用】

    为了增强android应用的用户体验,我们可以在一些Button按钮上自定义动态的设置一些样式,比如交互时改变字体、颜色、背景图等。 今天来看一个通过重写Button来动态实...2016-09-20
  • Android自定义WebView网络视频播放控件例子

    下面我们来看一篇关于Android自定义WebView网络视频播放控件开发例子,这个文章写得非常的不错下面给各位共享一下吧。 因为业务需要,以下代码均以Youtube网站在线视...2016-10-02
  • 详解.NET Core 3.0 里新的JSON API

    这篇文章主要介绍了详解.NET Core 3.0 里新的JSON API,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-09-22
  • 自定义jquery模态窗口插件无法在顶层窗口显示问题

    自定义一个jquery模态窗口插件,将它集成到现有平台框架中时,它只能在mainFrame窗口中显示,无法在顶层窗口显示. 解决这个问题的办法: 通过以下代码就可能实现在顶层窗口弹窗 复制代码 代码如下: $(window.top.documen...2014-05-31
  • 自定义feignClient的常见坑及解决

    这篇文章主要介绍了自定义feignClient的常见坑及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-10-20
  • .net数据库操作框架SqlSugar的简单入门

    这篇文章主要介绍了.net数据库操作框架SqlSugar的简单入门,帮助大家更好的理解和学习使用.net技术,感兴趣的朋友可以了解下...2021-09-22
  • pytorch 自定义卷积核进行卷积操作方式

    今天小编就为大家分享一篇pytorch 自定义卷积核进行卷积操作方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-05-06
  • ASP.NET Core根据环境变量支持多个 appsettings.json配置文件

    这篇文章主要介绍了ASP.NET Core根据环境变量支持多个 appsettings.json配置文件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-09-22
  • 记一次EFCore类型转换错误及解决方案

    这篇文章主要介绍了记一次EFCore类型转换错误及解决方案,帮助大家更好的理解和学习使用asp.net core,感兴趣的朋友可以了解下...2021-09-22
  • PHP YII框架开发小技巧之模型(models)中rules自定义验证规则

    YII的models中的rules部分是一些表单的验证规则,对于表单验证十分有用,在相应的视图(views)里面添加了表单,在表单被提交之前程序都会自动先来这里面的规则里验证,只有通过对其有效的限制规则后才能被提交,可以很有效地保证...2015-11-24
  • jquery自定义插件开发之window的实现过程

    这篇文章主要介绍了jquery自定义插件开发之window的实现过程的相关资料,需要的朋友可以参考下...2016-05-09
  • C#自定义事件监听实现方法

    这篇文章主要介绍了C#自定义事件监听实现方法,涉及C#事件监听的实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25
  • 详解ASP.NET Core 中基于工厂的中间件激活的实现方法

    这篇文章主要介绍了ASP.NET Core 中基于工厂的中间件激活的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-09-22
  • C#使用Ado.Net更新和添加数据到Excel表格的方法

    这篇文章主要介绍了C#使用Ado.Net更新和添加数据到Excel表格的方法,较为详细的分析了OLEDB的原理与使用技巧,可实现较为方便的操作Excel数据,需要的朋友可以参考下...2020-06-25