Popular MVC框架请求响应验签加签使用示例
简介
此项目用于演示使用popularmvc提供的加签、验签功能,以及如何定制自己的加签验签算法。
- 请求参数验签,使用
@RequiredSign(scope = SignScope.REQUEST)
注解修饰接口即可- 响应信息加签,使用
@RequiredSign(scope = SignScope.RESPONSE)
注解修饰接口即可- 指定自定义加签算法,使用
@RequiredSign(scope = SignScope.REQUEST, type = MD5SignEncryptHandler.class)
注解修饰接口即可,MD5SignEncryptHandler
是自定义验签算法的并实现了SignEncryptHandler
的接口。- 指定自定义验签算法,使用
@RequiredSign(scope = SignScope.RESPONSE, type = MD5SignEncryptHandler.class)
注解修饰接口即可
验签算法说明
敬请期待!
项目示例
1 项目结构
-
项目结构
│ pom.xml │ README.md │ └─src ├─main │ ├─java │ │ └─com │ │ └─danyuanblog │ │ └─framework │ │ └─demo │ │ └─popularmvc │ │ │ StartDemoApplication.java │ │ │ │ │ ├─controller │ │ │ │ TestCustomSignController.java │ │ │ │ TestSignController.java │ │ │ │ │ │ │ └─dto │ │ │ AccountInfo.java │ │ │ IgnoreRequestFiledSignRequest.java │ │ │ SignTestRequest.java │ │ │ SignTestResponse.java │ │ │ │ │ └─security │ │ MD5SignEncryptHandler.java │ │ │ └─resources │ application.yml │ └─test └─java └─com └─danyuanblog └─framework └─popular └─mvc
-
引入模块依赖,在
pom.xml
添加
<dependency>
<groupId>com.danyuanblog.framework</groupId>
<artifactId>popular-web-mvc</artifactId>
<version>${popular-web-mvc.version}</version>
</dependency>
2 启用PopularMvc框架
/**
* Title StartDemoApplication.java
* Description
* @author danyuan
* @date Oct 31, 2020
* @version 1.0.0
* site: www.danyuanblog.com
*/
package com.danyuanblog.framework.demo.popularmvc;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.danyuanblog.framework.popularmvc.annotation.EnablePopularMvc;
@SpringBootApplication
@EnablePopularMvc
public class StartDemoApplication {
public static void main(String[] args) {
SpringApplication.run(StartDemoApplication.class, args);
}
}
3 配置信息
秘钥信息配置如下
application.yml
popularmvc:
api:
channels:
default: #用于不区分渠道信息的应用
default: #默认的秘钥信息
enable: true
#用于对称加解密、生成数字签名、验证数字签名的秘钥
secret: "123456"
keyPair: #用于非对称加解密的秘钥对
privateSecret: ""
publicSecret: ""
appId1: #某个应用下的秘钥信息
enable: true
#用于对称加解密、生成数字签名、验证数字签名的秘钥
secret: "7123456"
keyPair: #用于非对称加解密的秘钥对
privateSecret: ""
publicSecret: ""
android:
default:
enable: true
#用于对称加解密、生成数字签名、验证数字签名的秘钥
secret: "6123456"
keyPair: #用于非对称加解密的秘钥对
privateSecret: ""
publicSecret: ""
ios:
default:
enable: true
secret: "12345678"
keyPair:
privateSecret: ""
publicSecret: ""
4 演示代码解析
4.1 使用默认的SHA1进行加签验签
加签验签的使用主要分两种应用场景:
- 对api调用者传递过来的接口请求信息和数字签名进行验签
- 将API返回信息生成数字签名后一并返回给接口调用者,接口调用者拿到后进行验签
- 请求响应均需要进行数字签名处理
示例代码如下所示。
-
接口源码
TestSignController.java
/** * Title TestSignController.java * Description * @author danyuan * @date Jan 4, 2021 * @version 1.0.0 * site: www.danyuanblog.com */ package com.danyuanblog.framework.demo.popularmvc.controller; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import java.math.BigDecimal; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.danyuanblog.framework.demo.popularmvc.controller.dto.AccountInfo; import com.danyuanblog.framework.demo.popularmvc.controller.dto.IgnoreRequestFiledSignRequest; import com.danyuanblog.framework.demo.popularmvc.controller.dto.SignTestRequest; import com.danyuanblog.framework.demo.popularmvc.controller.dto.SignTestResponse; import com.danyuanblog.framework.popularmvc.annotation.IgnoreSign; import com.danyuanblog.framework.popularmvc.annotation.RequiredSign; import com.danyuanblog.framework.popularmvc.consts.SignScope; @Api(tags = "测试接口验签加签功能") @RestController @Slf4j public class TestSignController { @PostMapping("testRequestCheckSign") @ApiOperation(value="测试请求验签功能", notes="测试请求验签功能") @RequiredSign(scope = SignScope.REQUEST) public String testRequestCheckSign( @RequestBody SignTestRequest req,@RequestParam String note, BigDecimal amount, @RequestParam("mobilePhone") String phone ) { log.info("phone:{},amount:{}", phone, amount); return "SUCCESS"; } @GetMapping("testResponseSign") @ApiOperation(value="测试响应加签功能", notes="测试响应加签功能") @RequiredSign(scope = SignScope.RESPONSE) public SignTestResponse testResponseSign() { BigDecimal amount = new BigDecimal(100); SignTestResponse resp = new SignTestResponse(); AccountInfo account = new AccountInfo(); account.setAmount(amount.setScale(2, BigDecimal.ROUND_HALF_UP)); account.setFreezeAmount(new BigDecimal(2856).setScale(2, BigDecimal.ROUND_HALF_UP)); account.setNote("this just a response sign test !"); resp.setPhone("13823117861"); resp.setAccount(account); resp.setDesc("test response !"); resp.setTest("校验后响应也不能为空哦!"); resp.setAge(26); return resp; } @PostMapping("testIgnoreRequestFiledSign") @ApiOperation(value="测试请求响应验签加签忽略字段等功能", notes="测试请求响应验签加签忽略字段等功能") @RequiredSign(scope = SignScope.BOTH) public String testIgnoreRequestFiledSign(@RequestBody IgnoreRequestFiledSignRequest req, @IgnoreSign @RequestBody SignTestRequest testReq, @RequestParam String email){ log.info("phone:{},account:{}", req.getPhone(), req.getAccount()); return "SUCCESS"; } }
-
用到的DTO信息
AccountInfo.java
/** * Title AccountInfo.java * Description * @author danyuan * @date Nov 14, 2020 * @version 1.0.0 * site: www.danyuanblog.com */ package com.danyuanblog.framework.demo.popularmvc.controller.dto; import java.io.Serializable; import java.math.BigDecimal; import lombok.Data; @Data public class AccountInfo implements Serializable{/** *serialVersionUID */ private static final long serialVersionUID = 1L; private String account; private BigDecimal amount; private BigDecimal freezeAmount; private String note; }
IgnoreRequestFiledSignRequest.java
/** * Title IgnoreRequestFiledSignRequest.java * Description * @author danyuan * @date Jan 4, 2021 * @version 1.0.0 * site: www.danyuanblog.com */ package com.danyuanblog.framework.demo.popularmvc.controller.dto; import java.io.Serializable; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import com.danyuanblog.framework.popularmvc.annotation.IgnoreSign; import lombok.Data; import lombok.experimental.Accessors; @Data @Accessors(chain = true) public class IgnoreRequestFiledSignRequest implements Serializable{/** *serialVersionUID */ private static final long serialVersionUID = 1L; private String desc; private String phone; @IgnoreSign @NotNull private AccountInfo account; @NotEmpty private String test; @NotNull private Integer age; }
SignTestRequest.java
/** * Title SignTestRequest.java * Description * @author danyuan * @date Nov 14, 2020 * @version 1.0.0 * site: www.danyuanblog.com */ package com.danyuanblog.framework.demo.popularmvc.controller.dto; import java.io.Serializable; import java.util.List; import java.util.Map; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import lombok.Data; @Data public class SignTestRequest implements Serializable{/** *serialVersionUID */ private static final long serialVersionUID = 1L; @NotEmpty private String name; private boolean sex; private Integer age; @NotNull @Size(min=1,max=5) private Map<String,String> tags; private List<String> likes; }
SignTestResponse.java
/** * Title SignTestResponse.java * Description * @author danyuan * @date Nov 14, 2020 * @version 1.0.0 * site: www.danyuanblog.com */ package com.danyuanblog.framework.demo.popularmvc.controller.dto; import java.io.Serializable; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import com.danyuanblog.framework.demo.popularmvc.controller.dto.AccountInfo; import lombok.Data; @Data public class SignTestResponse implements Serializable{/** *serialVersionUID */ private static final long serialVersionUID = 1L; private String desc; private String phone; private AccountInfo account; @NotEmpty private String test; @NotNull private Integer age; }
4.2 使用自定义的算法进行加签验签
-
新增自定义签名算法处理器
MD5SignEncryptHandler.java
/** * Title MD5SignEncryptHandler.java * Description * @author danyuan * @date Jan 4, 2021 * @version 1.0.0 * site: www.danyuanblog.com */ package com.danyuanblog.framework.demo.popularmvc.security; import org.springframework.stereotype.Component; import com.danyuanblog.framework.popularmvc.encrypt.SignEncryptHandler; import com.danyuanblog.framework.popularmvc.utils.EncryptUtils; @Component public class MD5SignEncryptHandler implements SignEncryptHandler { /** * @author danyuan */ @Override public String sign(String secrect, String body) { return EncryptUtils.encryptMD5Hex(secrect, body); } }
只需要将前面示例中的
@RequiredSign(scope = SignScope.REQUEST, type = MD5SignEncryptHandler.class)
的type指定为该类即可实现自定义验签算法