操作过滤器—MVC中使用操作过滤器实现JWT权限认证

操作,过滤器,mvc,使用,实现,jwt,权限,认证 · 浏览次数 : 138

小编点评

## 操作过滤器实现JWT鉴权 **什么是操作过滤器?** 操作过滤器是在Action执行的前和后进行调用执行的过滤器接口。与授权过滤器一样,它不是在刚开上来就执行授权过滤器,而是在Action执行时进行调用。操作过滤器的实现了是 `IAsyncActionFilter` 或 `IActionFilter` 接口。 **操作过滤器实现操作过滤器重新定义Filter:** * `OnActionExecuted` 方法在Action执行后执行。 * `OnActionExecuting` 方法在Action执行前执行。 **具体代码示例:** ```csharp public class MyAuthorizeFilterAttribute : Attribute, IActionFilter { // ... public void OnActionExecuting(ActionExecutingContext context) { // 获取token var authHeader = context.HttpContext.Request.Headers[\"Authorization\"]; if (string.IsNullOrWhiteSpace(authHeader)) { // 返回错误信息 } // 验证token有效期 if (!isTokenExpire(authHeader)) { // 返回错误信息 } // 执行业务逻辑 } // ... } ``` **验证:** 操作过滤器实现的接口部分代码没有改动,只改动过滤器的书写,所以和上篇测试验证方法一致。 **归纳总结:** * 操作过滤器是在Action执行时进行调用执行的过滤器接口。 * 它比授权过滤器在执行时机有所不同,是在Action执行前和后。 * 它是 IAsyncActionFilter 或 IActionFilter 接口的实现类。 * 当验证token有效期失败时,应该返回错误信息。

正文

前言

上一篇文章分享了授权过滤器实现JWT进行鉴权,文章链接:授权过滤器—MVC中使用授权过滤器实现JWT权限认证,接下来将用操作过滤器实现昨天的JWT鉴权。

一、什么是操作过滤器?

​ 与授权过滤器大部分一样,只是执行的时机和继承的接口有所不同。操作过滤器是在Action执行的前和后进行调用执行。而不是像授权过滤器一样,在刚开上来就执行授权过滤器。操作过滤器的实现了是 IAsyncActionFilterIActionFilter 接口。
image

二、操作过滤器实现

操作过滤器重新定义Filter:

继承类Attribute, 接口MyAuthorizeFilterAttribute ,然后实现接口OnActionExecuted方法和OnActionExecuting方法,提供更多的对Action执行处理方法。此处在Action执行时书写自定义业务逻辑。

 /// <summary>
    /// 授权过滤器
    /// </summary>
    public class MyAuthorizeFilterAttribute : Attribute, IActionFilter
    {
       #region IActionFilter 操作过滤器实现

        /// <summary>
        /// Action执行后
        /// </summary>
        /// <param name="context"></param>
        public void OnActionExecuted(ActionExecutedContext context)
        {

        }
        /// <summary>
        /// Action执行前
        /// </summary>
        /// <param name="context"></param>
        public void OnActionExecuting(ActionExecutingContext context)
        {
            var authHeader = context.HttpContext.Request.Headers["Authorization"];
            if (string.IsNullOrWhiteSpace(authHeader))
            {
                //var json =  JsonConvert.SerializeObject(new OperationResult(OperationResultType.Error, "保存失败"));
                //此接口必须携带token访问!
                context.Result = new ContentResult()
                {

                    Content = "此接口必须携带token访问,请登录携带Token访问",
                    ContentType = "text/html"//application/json
                };
            }
            else //字段值不为空
            {
                authHeader = authHeader.ToString().Replace("Bearer", "").Trim();//去掉Bearer字串
                if (authHeader == "")
                {
                    context.Result = new ContentResult()
                    {
                        Content = "token验证失败:您没有权限调用此接口,请登录重新获取Token",
                        ContentType = "text/html"
                    };
                }
                else
                {
                    LoginUserInfo LoginInfo = JwtHelper.GetJwtDecode(authHeader);
                    string UserName = LoginInfo.username;
                    string PassWord = LoginInfo.pwd;
                    double ExpireTimeStamp = LoginInfo.exp;
                    if (isTokenExpire(ExpireTimeStamp)) //这里应该验证有效期
                    {
                        //token验证失败:您没有权限调用此接口,请登录获取Token
                        context.Result = new ContentResult()
                        {
                            Content = "token验证失败:您没有权限调用此接口,请登录重新获取Token",
                            ContentType = "text/html"
                        };
                    }
                }

            }
        }
        #endregion

        /// <summary>
        /// 时间戳字符串
        /// </summary>
        /// <param name="timestamp"></param>
        /// <returns></returns>
        private bool isTokenExpire(double timestamp)
        {
            try
            {
                System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));//当地时区
                var expireTime = startTime.AddSeconds(timestamp);
                if (expireTime > DateTime.Now)
                {
                    return false;//未过期
                }
                else
                {
                    return true;//已过期
                }
            }
            catch (Exception ex)
            {
                return true;
            }
        }

    }

其他实现代码和上篇保持一致:

三、验证:

​ 操作过滤器实现的接口部分代码没有改动,只改动过滤器的书写,所以和上篇测试验证方法一致。

未授权访问:

不携带Token访问:
image

授权访问:

获取Token:
image

携带Token访问:
image

与操作过滤器—MVC中使用操作过滤器实现JWT权限认证相似的内容:

操作过滤器—MVC中使用操作过滤器实现JWT权限认证

## 前言 上一篇文章分享了授权过滤器实现JWT进行鉴权,文章链接:[授权过滤器—MVC中使用授权过滤器实现JWT权限认证](https://www.cnblogs.com/wml-it/p/17612434.html),接下来将用操作过滤器实现昨天的JWT鉴权。 ## 一、什么是操作过滤器? ​

资源过滤器—MVC中使用资源过滤器实现不执行Action方法体读取缓存信息返回

## 前言 上两篇文章分享了过滤器实现JWT进行鉴权,分别是通过授权过滤器和操作过滤器实现,这两个过滤器也是最常用的。文章链接:[授权过滤器—MVC中使用授权过滤器实现JWT权限认证](https://www.cnblogs.com/wml-it/p/17612434.html),[操作过滤器—MV

授权过滤器—MVC中使用授权过滤器实现JWT权限认证

## 一、什么是过滤器? ### 过滤器定义: ​ 过滤器与中间件很相似,**过滤器(Filters)**可在**管道(pipeline)**特定阶段(particular stage)前或后执行操作,可以将过滤器视为**拦截器(interceptors)**。在.NET MVC开发中,权限验证是非

【VS Code 与 Qt6】运用事件过滤器批量操作子级组件

如果某个派生自 QObject 的类重写 eventFilter 方法,那它就成了事件过滤器(Event Filter)。该方法的声明如下: virtual bool eventFilter(QObject *watched, QEvent *event); watched 参数是监听事件的对象,即

驱动开发:文件微过滤驱动入门

MiniFilter 微过滤驱动是相对于`SFilter`传统过滤驱动而言的,传统文件过滤驱动相对来说较为复杂,且接口不清晰并不符合快速开发的需求,为了解决复杂的开发问题,微过滤驱动就此诞生,微过滤驱动在编写时更简单,多数`IRP`操作都由过滤管理器`(FilterManager或Fltmgr)`所接管,因为有了兼容层,所以在开发中不需要考虑底层`IRP`如何派发,更无需要考虑兼容性问题,用户只需

[转帖]Shell三剑客之sed

目录 Shell三剑客sed工具sed 流编辑器的工作过程sed命令格式与选项操作符sed命令的常用选项sed命令的打印功能默认打印方式sed命令的寻址打印文本模式过滤行内容 sed的删除操作通过行号进行删除匹配字符串内容删除字符串搭配正则进行删除删除空行的三种方法 sed命令替换符进行大小写的替换

【Azure 存储服务】使用REST API操作Azure Storage Table,删除数据(Delete Entity)

问题描述 使用Azure Storage Table的REST API,实现根据过滤条件删除满足条件的数据,调用方法为 Delete Entity (Azure Storage) 问题实现 第一步:通过Azure Stroage 门户或者是其他工具(如:Azure Storage Explorer)

【Azure 服务总线】如何批量删除Azure Service Bus中的Topics(数量较多,需要过滤后批量删除)

问题描述 Azure Service Bus 的门户操作页面上,是否可以批量删除其中的Topics呢? 问题解答 Azure Service Bus门户或Service Bus Explorer工具没有提供批量删除Topic的方法。但是可以自己写脚本删除,并且可以在删除的时候自定义过滤条件。 以Py

[转帖]redis操作 + StrictRedis使用

https://www.cnblogs.com/szhangli/p/9979600.html Redis string类型 字符串类型是 Redis 中最为基础的数据存储类型。 它在 Redis 中是二进制安全的,这便意味着该类型可以接受任何格式的数据。 如JPEG图像数据或Json对象描述信息等

[转帖]文件操作之zip、bzip2、gzip、tar命令

文件操作之zip、bzip2、gzip、tar命令 原创 丁同学19902015-10-15 00:02:51博主文章分类:liunx基础©著作权 文章标签linux tarlinux文件压缩linux压缩文件linux命名方式linux gzip文章分类运维阅读数2808 先讲些简单的概念,因为对