【实用工具】SpringBoot实现接口签名验证
需求场景
由于项目需要开发第三方接口给多个供应商,为保证Api接口的安全性,遂采用Api接口签名验证。
Api接口签名验证主要防御措施为以下几个:
- 请求发起时间得在限制范围内
- 请求的用户是否真实存在
- 是否存在重复请求
- 请求参数是否被篡改
项目路径
https://gitee.com/charles_ruan/easy-sign
代码实现
不同的客户端有着不同的appSecret。
- 通过密钥可以为
不同的客户端(调用方) 分配不同的appSecret,来区分不同客户端app(调用方)。 - 将获取到的appSecret 参与到
sign(签名)的生成,保证了客户端的请求签名是由我们后台控制的。
定义切面,拦截带SignatureValidation方法。
- 获取方法上的参数,存入
SortedMap - 判断参数是否合法
- 判断appId是否存在对应的secret
- 判断时间戳是否有效
- 进行签名校验
@Slf4j
@Aspect
public class SignAspect {@Before("@annotation(signatureValidation)")public void doBefore(SignatureValidation signatureValidation) throws Throwable {// 接收到请求,记录请求内容HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();SortedMap<String, String> allParams = HttpUtils.getAllParams(request);// 1、获取请求sign签名参数,String sign = allParams.get("sign");if (StrUtil.isBlank(sign)) {throw new RuntimeException("sign不能为空");}// 2、获取请求参数secretString appId = allParams.get("appId");String appSecret = getAppSecret(appId);if (StrUtil.isBlank(appSecret)) {throw new RuntimeException("appId不合法");}// 3、获取请求参数timestamp 时间戳,String timestamp = allParams.get("timestamp");if (StrUtil.isBlank(timestamp)) {throw new RuntimeException("timestamp不能为空");}//3. 比较时间,120s内为合法请求if (Math.abs(Long.parseLong(timestamp) - System.currentTimeMillis()) > 120000) {throw new RuntimeException("timestamp失效");}allParams.put("secret", appSecret);verifySign(allParams);}private void verifySign(SortedMap<String, String> allParams) {// 对方签名String sign = allParams.get("sign");allParams.remove("sign");String mySign = SecureUtil.md5(JSONUtil.toJsonStr(allParams)).toUpperCase();log.info("验签,对方签名:{},我方签名:{}", sign, mySign);// 验签Assert.isTrue(StrUtil.equals(sign, mySign), "验签失败");}public String getAppSecret(String appId) {Map<String, String> map = new HashMap<>();map.put("zs001", "asd123fhg3b7fgh7dfg");map.put("ls001", "hghfgh123btgfyh1212");return map.get(appId);}
}
利用nonce参数,可以防止重复提交,在签名验证成功后,判断是否重复提交,原理就是结合redis,判断是否已经提交过
public boolean isReplayAttack(String appId, String timeStamp, String nonce, String signature) {StringBuilder redisKey = new StringBuilder();redisKey.append("IS_REPLAY_ATTACK").append(":").append(Constant.APP_ID).append(":").append(appId).append(Constant.TIME_STAMP).append(":").append(timeStamp).append(Constant.NONCE).append(":").append(nonce).append(Constant.SIGN).append(":").append(signature);Object value = redisTemplate.opsForValue().get(redisKey);if (value != null && StringUtils.equals(signature, value.toString()))return false;elseredisTemplate.opsForValue().set(redisKey, signature, 1000 * 50);return false;}
标题复制10行,并且每行大于10个字符 标题复制10行,并且每行大于10个字符 标题复制10行,并且每行大于10个字符 标题复制10行,并且每行大于10个字符 标题复制10行,并且每行大于10个字符 标题复制10行,并且每行大于10个字符 标题复制10行,并且每行大于10个字符 标题复制10行,并且每行大于10个字符 标题复制10行,并且每行大于10个字符 标题复制10行,并且每行大于10个字符

相关文章:
【实用工具】SpringBoot实现接口签名验证
需求场景 由于项目需要开发第三方接口给多个供应商,为保证Api接口的安全性,遂采用Api接口签名验证。 Api接口签名验证主要防御措施为以下几个: 请求发起时间得在限制范围内请求的用户是否真实存在是否存在重复请求请求参数是否被篡改 项目…...
DDR基础
欢迎关注我的博客网站nr-linux.com,图片清晰度和,排版会更好些,文章优先更新至博客站。 DDR全称Double Data Rate Synchronous Dynamic Random Access Memory,是当代处理器必不可少的存储器件之一。本文关于DDR介绍的核心点如下&…...
理解find命令
find命令使用通配符,而不是正则表达式 对于如下两个命令 find ./ -name *txt 和 find ./ -name \*txt 这两个命令之间的区别在于 shell 对通配符字符 * 的解释和展开方式不同。 find ./ -name *txt:在这个命令中,shell 在将命令传递给 fin…...
OpenCV教程——调整图像亮度与对比度,绘制形状和文字
调整图像亮度与对比度 1.图像变换 图像变换通常有两种方式: 像素变换:点操作邻域操作:区域 调整图像亮度和对比度属于像素变换(点操作)。 2.调整图像亮度与对比度 可以通过以下公式调整图像的亮度和对比度&#…...
Python模块篇:函数/类/变量和常量/注释/导入和使用
大家好,我是辣条哥!本期应邀写了一些Python模块相关内容~ Python模块是一种组织Python代码的方式,它将相关的代码放在一个文件中,以便于重用和维护。Python模块可以包含函数、类、变量和常量等,可以被其他Python程序导…...
Java反射和动态代理
反射 反射允许对封装类的成员变量、成员方法和构造方法的信息进行编程访问 成员变量:修饰符、名字、类型、get/set值 构造方法:修饰符、名字、形参、创建对象 成员方法:修饰符、名字、形参、返回值、抛出的异常、获取注解、运行方法 获取…...
[NOIP2004 提高组] 津津的储蓄计划(思路+代码详解)Python实现
题目描述 津津的零花钱一直都是自己管理。每个月的月初妈妈给津津300 元钱,津津会预算这个月的花销,并且总能做到实际花销和预算的相同。 为了让津津学习如何储蓄,妈妈提出,津津可以随时把整百的钱存在她那里,到了年…...
分布式搜索引擎es 面试突击
es elastocsearch 倒排索引是在数据查询之前建立,在查询的时候可以直接通过关键词定位到文档内容。用空间换时间 分布式架构原理说一下? es底层是基于lucene来的 大概就是一个用于全文检索的jar包 用es来做分布式的搜索引擎 可以承载一秒钟几千的…...
社会心理学的六个经典实验
社会心理学的六个经典实验 社会心理学(Social Psychology)是一门研究我们周围情境的力量的科学,尤其关注我们是如何看待他人,如何影响他人的。更确切地说,社会心理学是一门就人们如何看待他人,如何影响他人…...
Java 单例模式详解
单例模式(Singleton Pattern)是一种常见的设计模式,它可以确保某个类只有一个实例,并提供对该实例的全局访问点。本文将详细介绍 Java 中所有单例模式实现,包括懒汉式、饿汉式、枚举式、双重检查锁定式、静态内部类式等…...
AI读心重磅突破登Nature!大脑信号1秒被看穿,还能预测未来画面
最近,来自洛桑联邦理工学院的研究团队提出了一种全新的方法,可以用AI从大脑信号中提取视频画面。论文已登Nature,却遭网友疯狂「打假」。 现在,AI不仅会读脑,还会预测下一个画面了! 利用AI,一个…...
【SAP Abap】X-DOC:SNRO - ABAP流水号应用
【SAP Abap】X-DOC:SNRO - ABAP流水号应用 1、定义表(字段域)2、定义流水号3、使用流水号4、测试程序 1、定义表(字段域) 2、定义流水号 Tcode: SNRO/SNUM, 根据以上创建的字段域 YDSNRO,创建对…...
基于AT89C51单片机的交通灯设计与仿真
点击链接获取Keil源码与Project Backups仿真图: https://download.csdn.net/download/qq_64505944/87763760?spm1001.2014.3001.5503 源码获取 主要内容: 设计一个能够控制十二盏交通信号灯的模拟系统,:利用单片机的定时器定时,令十字路口…...
MySQL系列三(定位慢SQL、SQL优化与索引优化)Using filesort
文章目录 1. 慢SQL1.1 定位慢SQL(慢查询日志)1.2 慢SQL优化整体思路 2. 索引优化3. SQL语句优化回表Using filesort 1. 慢SQL 1.1 定位慢SQL(慢查询日志) 在mysql 配置文件中 (my.conf),进行下面配置&…...
免费使用GPT-4.0?【AI聊天 | GPT4教学】 —— 微软 New Bing GPT4 申请与使用保姆级教程
目录 认识 New Bing 2. 注册并登录 Microsoft 账号 3. 如何免科学上网使用 New Bing? 4. 加入 WaitList 候补名单 5. 使用 New Bing! 6. 使用 Skype 免科学上网访问 New Bing! 7. 在 Chrome 浏览器中使用 New Bing! 8. 总…...
渲染对电脑伤害大吗_如何减少渲染伤机?
虽然说摄影穷三代,但想要自己的本地配置跟上自己的创作速度,高昂的硬件配置支出也可以让自己穷一段时间。CG制作过程中,渲染是必不可少的一步,而且这一步也是很吃“机器”的,那很多人也会担心,如果经常用自…...
非线性最小二乘
非线性最小二乘 目录 文章目录 非线性最小二乘目录 [toc]1 非线性最小二乘估计3 非线性最小二乘的实现 1 非线性最小二乘估计 在经典最小二乘法估计中,假定被解释变量的条件期望是关于参数的线性函数,例如 E ( y ∣ x ) a b x E(y|x) abx E(y∣x)a…...
23.5.7总结(学习通项目思路)
项目: 1.登录修改:删除数据库中的状态,通过使用 ConcurrentHashMap来作为是否在线的判断,通过设定一个退出的按钮,发消息给服务端主动移除对应的值。 2.注册:增加了手机号的填写,正则判断&…...
如何生成api接口获取宝贝商品详情,商品详情接口,产品详情
API (Application Programming Interface)是指应用程序接口,它是一种通过编写一组统一的规则,开发一个软件来与其他应用程序进行通讯的技术。API可以方便应用程序之间的交流和数据共享,以及增强应用程序的功能。 在现代应用程序中࿰…...
微服务---Redis实用篇-黑马头条项目-登录功能(短信验证缓存,用户信息缓存)
黑马头条项目-登录功能(短信验证缓存,用户信息缓存) 1、短信登录 1.1、导入黑马点评项目 1.1.1 、导入SQL 1.1.2、有关当前模型 手机或者app端发起请求,请求我们的nginx服务器,nginx基于七层模型走的事HTTP协议,可以实现基于Lua直接绕开t…...
C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...
微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
uniapp手机号一键登录保姆级教程(包含前端和后端)
目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号(第三种)后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...
【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制
目录 节点的功能承载层(GATT/Adv)局限性: 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能,如 Configuration …...
windows系统MySQL安装文档
概览:本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容,为学习者提供全面的操作指导。关键要点包括: 解压 :下载完成后解压压缩包,得到MySQL 8.…...
