前言:之前工作中做过两个功能,就是之前写的这两篇博客,最近几天有个想法,给它做成一个springboot的start启动器,直接引入依赖,写好配置就能用了

springboot使用自定义注解实现接口参数解密,普通字段,json,集合

使用反射实现@RequestBody的参数校验功能

现在,它来了。

项目地址:

gitee:https://gitee.com/vhukze/master-key

githubhttps://github.com/vhukze/master-key

目录

版本更新记录

最新版本:1.3

介绍

软件架构

配置教程

1.引入依赖

2.配置

3.注意事项

使用说明

不同传参方式示例

1.json格式传参

2.text格式传参

不同参数类型示例

1.自定义实体类

2.基础数据类型或其包装类

3.集合类型

4.map类型

自定义解密过程

不同接口使用不同解密方法

 validation模块注解校验

最后


版本更新记录

更新的功能具体使用示例已经更新到博文中,请在目录中找到对应位置查看

最新版本:1.3

新增map类型参数解密;

新增不同接口不同解密方式配置;

1.2版本

新增全局解密配置和忽略解密注解;

新增自定义解密过程接口;

介绍

用来实现接口参数解密的工具,只需引入依赖,在配置文件写明加密的配置,在接口上使用指定注解即可实现该接口的参数解密。并支持使用validation模块的注解进行参数校验,支持分组校验功能

支持的对称加密方式:SM4,AES,DES,DESede 支持的非对称加密方式:RSA,SM2

软件架构

使用java8,springboot2.x.x,一个简单的springboot starter 启动器,功能中用到的工具类是hutool

配置教程

1.引入依赖

  1. <dependency>
  2. <groupId>io.github.vhukze</groupId>
  3. <artifactId>master-key-spring-boot-starter</artifactId>
  4. <version>目前最新版本</version>
  5. </dependency>

2.配置

注册参数解析器

  1. import com.vhukze.masterkey.master.DecodeResolver;
  2. import org.springframework.context.annotation.Configuration;
  3. import org.springframework.web.method.support.HandlerMethodArgumentResolver;
  4. import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
  5. import javax.annotation.Resource;
  6. import java.util.List;
  7. /**
  8. * webmvc配置
  9. */
  10. @Configuration
  11. public class MasterKeyConfig implements WebMvcConfigurer {
  12. @Resource
  13. private DecodeResolver decodeResolver;
  14. /**
  15. * 注册自定义HandlerMethodArgumentResolver 接口参数解密
  16. */
  17. @Override
  18. public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
  19. resolvers.add(decodeResolver);
  20. }
  21. }

对称加密配置示例(配置到application.yml中)

  1. master-key:
  2. # 加密方式
  3. encode: SM4
  4. # 使用json格式参数时,解密之前json的key 不配置此参数则代表使用text格式参数,只传递加密后的字符串
  5. json-key: str
  6. # 加密模式
  7. mode: CBC
  8. # 填充方式
  9. padding: ISO10126Padding
  10. # 秘钥
  11. key: 1234123412ABCDEF
  12. # 盐值
  13. salt: ABCDEF1234123412
  14. # 是否开启全局解密 默认false
  15. global-decode: false

对称加密配置项的可配置值

加密方式(encode) 加密模式(mode) 填充方式(padding)
SM4 NONE NoPadding
AES CBC ZeroPadding
DES CFB ISO10126Padding
DESede CTR OAEPPadding
CTS PKCS1Padding
ECB PKCS5Padding
OFB SSL3Padding
PCBC

非对称加密配置示例

  1. master-key:
  2. # 加密方式
  3. encode: SM2
  4. # 使用json格式参数时,解密之前json的key 不配置此参数则代表使用text格式参数,只传递加密后的字符串
  5. json-key:
  6. # 公钥
  7. public-key: MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEDRhJQbkA5SKceAaJmtdOBiRzCqwei4WRzAkBrZ9SkBZhZ1zC4nteRLVi754MsI/8vsiNK2lV518E8RaNw+mnLA==
  8. # 私钥
  9. private-key: MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQ
  10. # 是否开启全局解密 默认false
  11. global-decode: false

3.注意事项

使用SM4和SM2国密加密算法时,需要引入国密加密的依赖 如下

  1. <dependency>
  2. <groupId>org.bouncycastle</groupId>
  3. <artifactId>bcprov-jdk15to18</artifactId>
  4. <version>1.69</version>
  5. </dependency>

使用说明

支持自定义实体类、基础数据类型及其包装类、集合类型。加密前参数格式跟正常请求接口时相同

不同传参方式示例

例如当前接口所需参数为:{“id”:1,”count”:4}

加密后为:c7dc378bf0c4da001466818765813a506b1a6b37e960b7ca

1.json格式传参

在配置文件配置好json-key,并使用配置的json-key构建json字符串,比如配置的json-key为str,json字符串如下

  1. {
  2. “str”:“c7dc378bf0c4da001466818765813a506b1a6b37e960b7ca”
  3. }

实际请求如下图

2.text格式传参

不配置json-key即为使用text格式传参

实际请求如下图

不同参数类型示例

使用text传参方式演示

接口使用@ParamsDecode注解,标明此接口需要参数解密,如下

  1. @ParamsDecode
  2. @PostMapping(“decode”)
  3. public String decode(Stock stock){
  4. return “”;
  5. }

如果在配置中开启了全局解密,则无需使用 @ParamsDecode注解,会对所有接口进行解密。可以使用@IngoreDecode注解标明此接口无需解密,如下

  1. @IgnoreDecode
  2. @PostMapping(“decode”)
  3. public String decode(Stock stock){
  4. return “”;
  5. }

1.自定义实体类

接口参数的实体类

  1. @Data
  2. public class Stock {
  3. private Integer id;
  4. private Integer count;
  5. }

加密前的请求参数: {“id”:1,”count”:4}

实际请求

接口接收到的参数

2.基础数据类型或其包装类

接口参数为一个int类型

加密前的请求参数:5

实际请求

接口接收到的参数

3.集合类型

接口参数为List<Integer>集合

加密前的请求参数:[1,2,3]

实际请求

接口接收到的参数

4.map类型

要处理map类型,还需要新增两个配置,如下

1、在注册参数解析器的MasterKeyConfig中新增下面内容

  1. @Resource
  2. private RequestMappingHandlerAdapter requestMappingHandlerAdapter;
  3. @PostConstruct
  4. public void init() {
  5. List<HandlerMethodArgumentResolver> newResolvers = new ArrayList<>();
  6. newResolvers.add(decodeResolver);
  7. newResolvers.addAll(requestMappingHandlerAdapter.getArgumentResolvers());
  8. requestMappingHandlerAdapter.setArgumentResolvers(newResolvers);
  9. }

2、在配置文件中开启允许循环依赖:spring.main.allow-circular-references=true

接口参数为Map

加密前的请求参数:{“id”:3, “count”:4}

实际请求

接口接收到的参数

自定义解密过程

新建一个类实现MkDecodeInterface接口,并实现其中decode方法,使用@Component注添加到ioc容器中即可,如下所示,是一个简单的去括号功能

注意:实现了自定义解密接口,就会使用自定义解密,配置文件的配置无效(全局解密和json-key配置不受影响)

  1. package com.vhukze.lockdemo.config;
  2. import com.vhukze.masterkey.abs.MkDecodeInterface;
  3. import org.springframework.stereotype.Component;
  4. /**
  5. * 集成自定义解密功能
  6. */
  7. @Component
  8. public class MkDecodeInterfaceImpl implements MkDecodeInterface {
  9. @Override
  10. public String decode(String before) {
  11. return before.replaceAll(“\\(“, “”).replaceAll(“\\)”, “”);
  12. }
  13. }

实际请求

接口接收到的参数

不同接口使用不同解密方法

为了解决项目中使用的不止一个加密方式,不同接口需要使用不同的解密方式

首先在配置文件中配置多个解密配置,示例如下:

一个全局解密配置和两个单独解密配置

  1. master-key:
  2. # 是否开启全局解密 默认false
  3. # global-decode: true
  4. # 加密方式
  5. encode: DESede
  6. # 解密前json的key
  7. json-key:
  8. # 加密模式
  9. mode: CBC
  10. # 填充方式
  11. padding: ISO10126Padding
  12. # 秘钥
  13. key: 1234123412ABCDEF12ABCDEF
  14. # 盐值
  15. salt: ABCDEF12
  16. # 多个解密配置 这个名称是自定义的,使用时在注解中指定
  17. config1:
  18. # 加密方式
  19. encode: AES
  20. # 解密前json的key
  21. json-key:
  22. # 加密模式
  23. mode: CBC
  24. # 填充方式
  25. padding: ISO10126Padding
  26. # 秘钥
  27. key: 1234123412ABCDEF
  28. # 盐值
  29. salt: ABCDEF1234123412
  30. config2:
  31. # 加密方式
  32. encode: DES
  33. # 解密前json的key
  34. json-key:
  35. # 加密模式
  36. mode: CBC
  37. # 填充方式
  38. padding: ISO10126Padding
  39. # 秘钥
  40. key: 1234123412ABCDEF
  41. # 盐值
  42. salt: ABCDEF12

使用时在注解中指定value字段值即可,如下

  1. @ParamsDecode(“config1”)
  2. @PostMapping(“decode”)
  3. public String decode(Stock stock) {
  4. return “”;
  5. }

指定value字段值之后,此接口便会使用注解中指定的配置解密

 validation模块注解校验

实现了一些常用的注解,并支持分组校验功能,目前实现的注解有以下这些

数据类型 注解
Integer、Long、Short @NotNull、@Max、@Min、@Null
String @NotNull、@NotBlank、@Size、@Null、@Pattern
集合类型 @NotNull、@NotEmpty、@Size、@Null

具体使用方式跟正常使用一样,下面有个示例

  1. @Data
  2. public class Stock {
  3. @Max(3)
  4. @NotNull(groups = Edit.class)
  5. private Integer id;
  6. @NotBlank(groups = {Add.class, Edit.class})
  7. private String name;
  8. @Min(3)
  9. private Integer count;
  10. public interface Add {
  11. }
  12. public interface Edit {
  13. }
  14. }
  1. @ParamsDecode
  2. @PostMapping(“decode”)
  3. public String decode(@Validated(value = Add.class) Stock stock) {
  4. return “”;
  5. }