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

【实用工具】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实现接口签名验证

需求场景 由于项目需要开发第三方接口给多个供应商&#xff0c;为保证Api接口的安全性&#xff0c;遂采用Api接口签名验证。 Api接口签名验证主要防御措施为以下几个&#xff1a; 请求发起时间得在限制范围内请求的用户是否真实存在是否存在重复请求请求参数是否被篡改 项目…...

DDR基础

欢迎关注我的博客网站nr-linux.com&#xff0c;图片清晰度和&#xff0c;排版会更好些&#xff0c;文章优先更新至博客站。 DDR全称Double Data Rate Synchronous Dynamic Random Access Memory&#xff0c;是当代处理器必不可少的存储器件之一。本文关于DDR介绍的核心点如下&…...

理解find命令

find命令使用通配符&#xff0c;而不是正则表达式 对于如下两个命令 find ./ -name *txt 和 find ./ -name \*txt 这两个命令之间的区别在于 shell 对通配符字符 * 的解释和展开方式不同。 find ./ -name *txt&#xff1a;在这个命令中&#xff0c;shell 在将命令传递给 fin…...

OpenCV教程——调整图像亮度与对比度,绘制形状和文字

调整图像亮度与对比度 1.图像变换 图像变换通常有两种方式&#xff1a; 像素变换&#xff1a;点操作邻域操作&#xff1a;区域 调整图像亮度和对比度属于像素变换&#xff08;点操作&#xff09;。 2.调整图像亮度与对比度 可以通过以下公式调整图像的亮度和对比度&#…...

Python模块篇:函数/类/变量和常量/注释/导入和使用

大家好&#xff0c;我是辣条哥&#xff01;本期应邀写了一些Python模块相关内容~ Python模块是一种组织Python代码的方式&#xff0c;它将相关的代码放在一个文件中&#xff0c;以便于重用和维护。Python模块可以包含函数、类、变量和常量等&#xff0c;可以被其他Python程序导…...

Java反射和动态代理

反射 反射允许对封装类的成员变量、成员方法和构造方法的信息进行编程访问 成员变量&#xff1a;修饰符、名字、类型、get/set值 构造方法&#xff1a;修饰符、名字、形参、创建对象 成员方法&#xff1a;修饰符、名字、形参、返回值、抛出的异常、获取注解、运行方法 获取…...

[NOIP2004 提高组] 津津的储蓄计划(思路+代码详解)Python实现

题目描述 津津的零花钱一直都是自己管理。每个月的月初妈妈给津津300 元钱&#xff0c;津津会预算这个月的花销&#xff0c;并且总能做到实际花销和预算的相同。 为了让津津学习如何储蓄&#xff0c;妈妈提出&#xff0c;津津可以随时把整百的钱存在她那里&#xff0c;到了年…...

分布式搜索引擎es 面试突击

es elastocsearch 倒排索引是在数据查询之前建立&#xff0c;在查询的时候可以直接通过关键词定位到文档内容。用空间换时间 分布式架构原理说一下&#xff1f; es底层是基于lucene来的 大概就是一个用于全文检索的jar包 用es来做分布式的搜索引擎 可以承载一秒钟几千的…...

社会心理学的六个经典实验

社会心理学的六个经典实验 社会心理学&#xff08;Social Psychology&#xff09;是一门研究我们周围情境的力量的科学&#xff0c;尤其关注我们是如何看待他人&#xff0c;如何影响他人的。更确切地说&#xff0c;社会心理学是一门就人们如何看待他人&#xff0c;如何影响他人…...

Java 单例模式详解

单例模式&#xff08;Singleton Pattern&#xff09;是一种常见的设计模式&#xff0c;它可以确保某个类只有一个实例&#xff0c;并提供对该实例的全局访问点。本文将详细介绍 Java 中所有单例模式实现&#xff0c;包括懒汉式、饿汉式、枚举式、双重检查锁定式、静态内部类式等…...

AI读心重磅突破登Nature!大脑信号1秒被看穿,还能预测未来画面

最近&#xff0c;来自洛桑联邦理工学院的研究团队提出了一种全新的方法&#xff0c;可以用AI从大脑信号中提取视频画面。论文已登Nature&#xff0c;却遭网友疯狂「打假」。 现在&#xff0c;AI不仅会读脑&#xff0c;还会预测下一个画面了&#xff01; 利用AI&#xff0c;一个…...

【SAP Abap】X-DOC:SNRO - ABAP流水号应用

【SAP Abap】X-DOC&#xff1a;SNRO - ABAP流水号应用 1、定义表&#xff08;字段域&#xff09;2、定义流水号3、使用流水号4、测试程序 1、定义表&#xff08;字段域&#xff09; 2、定义流水号 Tcode: SNRO/SNUM&#xff0c; 根据以上创建的字段域 YDSNRO&#xff0c;创建对…...

基于AT89C51单片机的交通灯设计与仿真

点击链接获取Keil源码与Project Backups仿真图&#xff1a; https://download.csdn.net/download/qq_64505944/87763760?spm1001.2014.3001.5503 源码获取 主要内容&#xff1a; 设计一个能够控制十二盏交通信号灯的模拟系统,:利用单片机的定时器定时&#xff0c;令十字路口…...

MySQL系列三(定位慢SQL、SQL优化与索引优化)Using filesort

文章目录 1. 慢SQL1.1 定位慢SQL&#xff08;慢查询日志&#xff09;1.2 慢SQL优化整体思路 2. 索引优化3. SQL语句优化回表Using filesort 1. 慢SQL 1.1 定位慢SQL&#xff08;慢查询日志&#xff09; 在mysql 配置文件中 &#xff08;my.conf)&#xff0c;进行下面配置&…...

免费使用GPT-4.0?【AI聊天 | GPT4教学】 —— 微软 New Bing GPT4 申请与使用保姆级教程

目录 认识 New Bing 2. 注册并登录 Microsoft 账号 3. 如何免科学上网使用 New Bing&#xff1f; 4. 加入 WaitList 候补名单 5. 使用 New Bing&#xff01; 6. 使用 Skype 免科学上网访问 New Bing&#xff01; 7. 在 Chrome 浏览器中使用 New Bing&#xff01; 8. 总…...

渲染对电脑伤害大吗_如何减少渲染伤机?

虽然说摄影穷三代&#xff0c;但想要自己的本地配置跟上自己的创作速度&#xff0c;高昂的硬件配置支出也可以让自己穷一段时间。CG制作过程中&#xff0c;渲染是必不可少的一步&#xff0c;而且这一步也是很吃“机器”的&#xff0c;那很多人也会担心&#xff0c;如果经常用自…...

非线性最小二乘

非线性最小二乘 目录 文章目录 非线性最小二乘目录 [toc]1 非线性最小二乘估计3 非线性最小二乘的实现 1 非线性最小二乘估计 在经典最小二乘法估计中&#xff0c;假定被解释变量的条件期望是关于参数的线性函数&#xff0c;例如 E ( y ∣ x ) a b x E(y|x) abx E(y∣x)a…...

23.5.7总结(学习通项目思路)

项目&#xff1a; 1.登录修改&#xff1a;删除数据库中的状态&#xff0c;通过使用 ConcurrentHashMap来作为是否在线的判断&#xff0c;通过设定一个退出的按钮&#xff0c;发消息给服务端主动移除对应的值。 2.注册&#xff1a;增加了手机号的填写&#xff0c;正则判断&…...

如何生成api接口获取宝贝商品详情,商品详情接口,产品详情

API (Application Programming Interface)是指应用程序接口&#xff0c;它是一种通过编写一组统一的规则&#xff0c;开发一个软件来与其他应用程序进行通讯的技术。API可以方便应用程序之间的交流和数据共享&#xff0c;以及增强应用程序的功能。 在现代应用程序中&#xff0…...

微服务---Redis实用篇-黑马头条项目-登录功能(短信验证缓存,用户信息缓存)

黑马头条项目-登录功能(短信验证缓存,用户信息缓存) 1、短信登录 1.1、导入黑马点评项目 1.1.1 、导入SQL 1.1.2、有关当前模型 手机或者app端发起请求&#xff0c;请求我们的nginx服务器&#xff0c;nginx基于七层模型走的事HTTP协议&#xff0c;可以实现基于Lua直接绕开t…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

conda相比python好处

Conda 作为 Python 的环境和包管理工具&#xff0c;相比原生 Python 生态&#xff08;如 pip 虚拟环境&#xff09;有许多独特优势&#xff0c;尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处&#xff1a; 一、一站式环境管理&#xff1a…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

大话软工笔记—需求分析概述

需求分析&#xff0c;就是要对需求调研收集到的资料信息逐个地进行拆分、研究&#xff0c;从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要&#xff0c;后续设计的依据主要来自于需求分析的成果&#xff0c;包括: 项目的目的…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡&#xff08;如 HAProxy、AWS NLB、阿里 SLB&#xff09;发起上游连接时&#xff0c;将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后&#xff0c;ngx_stream_realip_module 从中提取原始信息…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...