背景:一个app的后台开发,现在想要对请求内容进行校验,防止请求内容被人篡改,目前的做法是前端发送请求时,对参数进行MD5摘要算法(中间加了些我们自己约定的规则),将算出来的MD5值附在请求里一起带过来,后台拿着前台传过来的参数进行相同规则的计算,将计算出来的MD5值和前台计算的值进行比较。

想法没什么问题,然而开发时发现在拦截器里获取到的已经是mapper后的对象了,拿不到原始请求的json串,自然也不好比较算出来的MD5值了。

查了下,前台是post请求数据是json类型,那request.getparameter()之类的就拿不到值了,要获得原始请求的json串,只能去流里面读了,那流读完一次就没法读了,最开始的想法是能不能在读流的地方,把原始请求留个备份啥的。debug跟了下整个请求处理的源码(spring 那一套),找到最终是在com.fasterxml.jackson.databind包里的ObjectMapper类里面去解析了流,并转成对应的对象。这是jackson-databind jar包的方法,

修改重打jar包肯定不现实,想了下本地建个同名的包,再建个同名的ObjectMapper类,自然就可以把原来jar包里的ObjectMapper类给覆盖掉了,试了下,可行。姑且算方案一吧。但这方法还是不太好,要建一个与项目不相干的包。

方案二,那我能想到的还是得想办法解决流只能读一次这个问题了,那就得想办法是不是可以把流再写回去,查了下,参考了网上的办法。

也就是在通过加过滤器,在过滤器里,把流读出来后,通过重写HttpServletRequestWrapper的getInputStream的方法,再把流的内容写回去。代码网上很多,大同小异。

public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {private final byte[] body;public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {super(request);body =  getBodyString(request).getBytes(Charset.forName("UTF-8"));}@Overridepublic BufferedReader getReader() throws IOException {return new BufferedReader(new InputStreamReader(getInputStream()));}@Overridepublic ServletInputStream getInputStream() throws IOException {final ByteArrayInputStream bais = new ByteArrayInputStream(body);return new ServletInputStream() {@Overridepublic int read() throws IOException {return bais.read();}@Overridepublic boolean isFinished() {return false;}@Overridepublic boolean isReady() {return false;}@Overridepublic void setReadListener(ReadListener readListener) {}};}public static String getBodyString(ServletRequest request) {try {return StreamUtil.readText(request.getInputStream());} catch (IOException e1) {throw ReqErrCodes.CUSTOM_PROMPT.exception("流内容解析失败");}}
}

@Order(1)
@WebFilter(filterName = "checkSignFilter", urlPatterns = "/*")
public class CheckSignFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("CheckSignFilter");HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;ServletRequest requestWrapper = new BodyReaderHttpServletRequestWrapper(httpRequest);String str = BodyReaderHttpServletRequestWrapper.getBodyString(requestWrapper);HttpServletRequest request = null;if(servletRequest instanceof HttpServletRequest){request = (HttpServletRequest)servletRequest;}String md5code = request.getHeader("MD5Code");String MD5ecode = MD5.getMessageDigest(str);if(!md5code.equals(MD5ecode)){// TODO}filterChain.doFilter(requestWrapper, servletResponse);}@Overridepublic void destroy() {}
}

转载于:https://www.cnblogs.com/boogieman/p/8289295.html

请求参数完整性校验,解决流只能写一次的问题相关推荐

  1. Struts2请求参数合法性校验机制

    在Action中通过代码执行数据校验 请求参数的输入校验途径一般分两种:客户端校验 :通过JavaScript 完成 (jquery validation插件),目的:过滤正常用户的误操作. 服务器校 ...

  2. 详解Spring MVC请求参数类型,解决中文乱码问题,自定义类型转换器,Spring MVC相关注解

    #SpringMVC SpringMVC请求 简单类型 简单类型包括:基本类型,基本类型的包装类型,字符串 编写Controller @RequestMapping("/param" ...

  3. GO请求参数规则校验(自定义校验规则、规则中文化)

    文章目录 1 简介 2 简单校验 3 自定义字段类型 4 结构层校验 5 翻译和自定义错误 6 国际化成中文 ​ 参数校验是开发中不可或缺的重要组成部分,本章节我们将介绍参数的校验,采用的是 go-p ...

  4. python get方法请求参数_如何解决TypeError get()在使用get方法的Python请求中恰好接受2个参数(给定3个)...

    在Python中使用Request对象时出现错误. 下面是我的代码. class APIDOC(Document): def request_api(self): method_type = self ...

  5. 解决流只能读一次的问题,getInputStream() has already been called for this request

    场景:在aop的日志中想获取 post请求的json数据时报错,因为在后台 控制器的接口中流已经读取了,导致日志这里获取就会报错,需要重写请求的 getInputStream  getReader,然 ...

  6. Spring Boot 2.x基础教程:JSR-303实现请求参数校验

    点击蓝色"程序猿DD"关注我 回复"资源"获取独家整理的学习资料! 作者 | 翟永超 来源 | didispace.com/spring-boot-learni ...

  7. Spring Boot 拦截器 请求参数MD5签名校验

    拦截器定义 /*** 拦截器 请求参数签名校验* Created by jiyang on 14:47 2017/12/14*/ @Component @Slf4j public class Para ...

  8. Springboot中请求参数校验

    1.添加依赖 <!-- 参数校验 --> <dependency><groupId>org.springframework.boot</groupId> ...

  9. java进行参数快捷校验,ehi-verification

    ehi-verification 项目介绍 一个好用的快速的参数校验框架 支持直接调用校验并提供Spring-webmvc拦截器对请求参数进行校验 软件架构 没啥架构,不强制依赖第三方Jar包 更新记 ...

  10. laravel框架中文手册_laravel请求参数校验方法

    对于后端开发而言,前端request请求中的参数校验是一个必不可少的环节.无论传来的参数是id还是email还是其他的参数,我们都要对参数的类型.大小.格式等等做这样或者那样的校验,然后才进行逻辑处理 ...

最新文章

  1. document.all与WEB标准
  2. 【ACM】杭电OJ 2044 2045
  3. robotframework常见问题解决汇总
  4. python输出个人信息_Python如何输出警告信息
  5. 记一次递归在我项目中所发挥的作用
  6. 人工智能:自由能理论,AI未来的数学模型
  7. C# C/S 图片验证码功能源码
  8. [mybatis]映射文件_select_resultMap_关联查询_association分步查询延迟加载
  9. java 图片的路径_【JAVA技术】如何展现绝对路径下的图片
  10. [原]防火墙安装配置(日志)
  11. 该虚拟机似乎正在使用中。 如果该虚拟机未在使用,请按“获取所有权(T)”按钮获取它的所有权。否则,请按“取消(C)”按钮以防损坏。 配置文件: D:\instractPath\Developmen
  12. 第四届全国大学生GIS应用技能大赛开发题答案(非官方)
  13. 2018华为网络技术大赛
  14. What Could Kill Testing?(什么可以终结测试)
  15. MessageBox confirm弹框确认和取消按钮的使用-回调
  16. 达内python第一次月考题目_月考来临!第一次月考远比你想象的重要!
  17. WordPress教程网站
  18. python 传奇服务端_夜光带你走进python开发 (三十二)传奇语言
  19. 计算机二三四级软考、志愿者实习、软著外观实用发明专利、著作、科研论文EI/SCI在大学期间野蛮成长方式
  20. 【预言】鲁迅名言一百年

热门文章

  1. 系统学习数字图像处理之形态学分析
  2. P.Laguna/AUTOMATIC DETECTION OF WAVE BOUNDARIES IN MULTILEAD ECG SIGNALS VALIDATION WITH THE CSE DB
  3. 如何对第一个值相同的列表中的元组求和
  4. Java韩顺平 | IO流专题 | 学习小记
  5. 数据结构--二叉树与森林记事本
  6. 【数据结构(C语言)】数据结构-内部排序
  7. 利用nginx+lua+redis实现反向代理方法教程
  8. 11月20日站立会议
  9. [js高手之路] dom常用节点属性兼容性详解与应用
  10. 【webpack】理解配置文件