当前位置: 首页 > news >正文

.Net Core 中间件验签

文章目录

    • 为什么是用中间件而不是筛选器?
    • 代码实现
    • 技术要点
      • context.Request.EnableBuffering()
      • 指针问题
    • 小结

为什么是用中间件而不是筛选器?

在这里插入图片描述

为什么要用中间件验签,而不是筛选器去验签?
1、根据上图我们可以看到,中间件在筛选器之前,而筛选往下就是我们写业务逻辑代码的控制器了。这就大大增加了我们被攻击的风险。
2、用筛选器我们需要在每个控制器上都添加相应的标识,如果需要校验的sign的控制器多的话,就增加了很多不必要的工作量,和风险,如果某个控制器一时疏忽忘记加筛选器的话就有可能会被攻击。

筛选器一般都是当数据得到信任的时候做验证,例如用户登录了,做功能的权限判定,中间件判定非信任数据

代码实现

 /// <summary>/// 验签中间件/// </summary>public class SignatureMiddleware{ /// <summary>/// 用户服务/// </summary>public UserService _userService { get; set; }private readonly RequestDelegate _next;/// <summary>/// 构造函数/// </summary>/// <param name="next">上下文</param>/// <param name="userService">用户服务注入</param>public SignatureMiddleware(RequestDelegate next, UserService userService){_next = next;_userService = userService;}/// <summary>/// 管道委托/// </summary>/// <param name="context">请求</param>/// <returns></returns>public async Task Invoke(HttpContext context){if (context.Request.Path.Value.StartsWith("/api/Order")){// 验证签名var isValidSignature = await ValidateSignatureAsync(context);if (isValidSignature.Item1){await _next(context);}else{context.Response.StatusCode = 403;await context.Response.WriteAsJsonAsync(AlwaysResult.Error(isValidSignature.Item2));}}else{await _next(context);}}private async Task<(bool, string)> ValidateSignatureAsync(HttpContext context){context.Request.EnableBuffering();//倒带string Postbody = string.Empty;string sign = context.Request.Headers[GlobalContext.SystemConfig.OpenApiSettings.SignName].ParseToString();string timestamp = context.Request.Headers[GlobalContext.SystemConfig.OpenApiSettings.Timestamp].ParseToString();string appkey = context.Request.Headers[GlobalContext.SystemConfig.OpenApiSettings.Appkey].ParseToString();//先根据Appkey查询这个账户的状态:UserExtend user = await _userService.GetForm(appkey);if (user != null){context.Request.Body.Position = 0;var readResult = await context.Request.BodyReader.ReadAsync();context.Request.BodyReader.AdvanceTo(readResult.Buffer.Start, readResult.Buffer.End);Postbody = Encoding.UTF8.GetString(readResult.Buffer.FirstSpan);string checksign = DESEncrypt.MD5(appkey + timestamp + Postbody + user.F_Account + appkey).ToLower();if (!checksign.Equals(sign)){return (false, "验签失败!");}else{context.Request.Body.Position = 0;//指针回拨return (true, "");}}else{return (false, "非法签名!");}}}

技术要点

context.Request.EnableBuffering()

ValidateSignatureAsync 方法为验证签名方法,方法内第一行中的:context.Request.EnableBuffering();的作用是允许http请求中的body重复读取,如果不加这个方法当数据在验签过程中读取出来之后到了控制器时,控制器中获取到的body就会是空值

指针问题

context.Request.Body.Position ;
代码中用到了两次,第一次使用的时候是将指针指向body的第一位。当读取出数据之后,指针会由第一位移动到最后一位,因此我们在读取完验签完成之后需要把指针从最后以为拨回到第一位。如果没有验签通过也就没有那个必要了。

小结

在学习过程中我们不仅要知其然还要知其所以然。
中间件:用于过滤非信任数据
过滤器:用于判定受信任的安全的数据

相关文章:

  • 微信小程序(五十八)分步表单多页面传值
  • Java后端面试经验分享,~纯分享
  • 【体验有奖】用 AI 画春天,函数计算搭建 Stable Diffusion WebUI
  • 矩阵消元-MIT
  • 【jeecgboot】微服务实战LISM
  • UDP数据报套接字编程
  • 【热门话题】前端框架发展史
  • PostMan测试文件上传
  • 2024Vue高频面试题
  • C/C++火柴棍等式
  • docker搭建firefiy iii
  • 深入了解 大语言模型(LLM)微调方法
  • 如何“使用Docker快速安装Jenkins,在CentOS7”?
  • Qt教程 — 3.4 深入了解Qt 控件:Input Widgets部件(3)
  • NFT数字藏品推广途径有哪些?CloudNEO免费个性定制方案,推广您的NFT
  • ES6指北【2】—— 箭头函数
  • [笔记] php常见简单功能及函数
  • 【MySQL经典案例分析】 Waiting for table metadata lock
  • 【个人向】《HTTP图解》阅后小结
  • Android开源项目规范总结
  • electron原来这么简单----打包你的react、VUE桌面应用程序
  • github指令
  • Git同步原始仓库到Fork仓库中
  • input实现文字超出省略号功能
  • JavaScript学习总结——原型
  • JDK9: 集成 Jshell 和 Maven 项目.
  • Laravel核心解读--Facades
  • PyCharm搭建GO开发环境(GO语言学习第1课)
  • ucore操作系统实验笔记 - 重新理解中断
  • XML已死 ?
  • 后端_MYSQL
  • 基于webpack 的 vue 多页架构
  • 如何抓住下一波零售风口?看RPA玩转零售自动化
  • 适配iPhoneX、iPhoneXs、iPhoneXs Max、iPhoneXr 屏幕尺寸及安全区域
  • 小而合理的前端理论:rscss和rsjs
  • 延迟脚本的方式
  • 自制字幕遮挡器
  • Spring第一个helloWorld
  • 阿里云服务器购买完整流程
  • 机器人开始自主学习,是人类福祉,还是定时炸弹? ...
  • ​configparser --- 配置文件解析器​
  • ​用户画像从0到100的构建思路
  • #NOIP 2014# day.1 生活大爆炸版 石头剪刀布
  • (23)Linux的软硬连接
  • (WSI分类)WSI分类文献小综述 2024
  • (ZT)北大教授朱青生给学生的一封信:大学,更是一个科学的保证
  • (附源码)spring boot儿童教育管理系统 毕业设计 281442
  • (附源码)springboot优课在线教学系统 毕业设计 081251
  • (附源码)ssm基于微信小程序的疫苗管理系统 毕业设计 092354
  • (附源码)计算机毕业设计ssm高校《大学语文》课程作业在线管理系统
  • (十)【Jmeter】线程(Threads(Users))之jp@gc - Stepping Thread Group (deprecated)
  • (四)模仿学习-完成后台管理页面查询
  • .bat批处理(八):各种形式的变量%0、%i、%%i、var、%var%、!var!的含义和区别
  • .L0CK3D来袭:如何保护您的数据免受致命攻击
  • .NET MAUI学习笔记——2.构建第一个程序_初级篇