Commit 03cb2164 authored by wangjinjing's avatar wangjinjing

Merge branch 'master' of http://192.168.168.218/wcyuee/szpt

parents 15a14144 2250347a
......@@ -11,6 +11,7 @@ import com.zksy.szpt.domain.HttpResultState;
import com.zksy.szpt.domain.po.AppStore;
import com.zksy.szpt.service.AppStoreService;
import com.zksy.szpt.util.EncryptUtil;
import com.zksy.szpt.util.RedisKeyValidator;
import com.zksy.szpt.util.SignatureUtil;
import com.zksy.szpt.util.UserContextHolder;
import org.slf4j.Logger;
......@@ -83,6 +84,16 @@ public class SignatureVerificationFilter extends OncePerRequestFilter {
return false;
}
// 验证nonce和timestamp合法性
if (!RedisKeyValidator.isValidString(nonce)) {
this.write(response, "不是合法的由数字和字母以及下划线组成的nonce:" + nonce);
return false;
}
if (!RedisKeyValidator.isValidTimestamp(timestampStr)) {
this.write(response, "不是合法的十位秒级时间戳timestamp:" + timestampStr);
return false;
}
// timestamp 10分钟内有效
long timestamp = Long.parseLong(timestampStr);
long currentTimestamp = System.currentTimeMillis() / 1000;
......@@ -94,7 +105,7 @@ public class SignatureVerificationFilter extends OncePerRequestFilter {
// 防止请求重放,nonce只能用一次,放在redis中,有效期 20分钟
String nonceKey = "api_signature:nonce:" + nonce;
if (Boolean.FALSE.equals(this.redisTemplate.opsForValue().setIfAbsent(nonceKey, "1", 20, TimeUnit.MINUTES))) {
this.write(response, "nonce无效");
this.write(response, "nonce无效:" + nonce);
return false;
}
......@@ -102,7 +113,7 @@ public class SignatureVerificationFilter extends OncePerRequestFilter {
AppStore appStore = this.appStoreService.getAppSecretInfo(appId);
String appSecret = appStore.getAppSecret();
if (!StringUtils.hasText(appSecret)) {
this.write(response, "appId无效");
this.write(response, "appId无效:" + appId);
return false;
}
......
package com.zksy.szpt.util;
import java.util.regex.Pattern;
public class RedisKeyValidator {
private static final String INVALID_CHARACTERS = "[\\x00\\x20\\x0A\\x0D\\x09]"; // 常见的无效字符
public static boolean isValidKey(String key) {
if (key == null || key.isEmpty()) {
return false;
}
return !key.matches(INVALID_CHARACTERS);
}
/**
*
* @param str
* @return
*/
public static boolean isValidString(String str) {
// 定义正则表达式,匹配字母、数字和下划线
String regex = "\\w+";
return Pattern.matches(regex, str);
}
/**
* 检查是否为有效的秒级时间戳
* @param timestamp
* @return
*/
public static boolean isValidTimestamp(String timestamp) {
// 检查是否为数字
if (!timestamp.matches("\\d+")) {
return false;
}
// 检查长度是否为10位(秒)
return timestamp.length() == 10;
}
}
......@@ -29,7 +29,7 @@ public class MainTest {
String nonce = "2";
String timestampStr = "21";
String appId = "1872576325743943682";
String appSecret = "21";
String appSecret = "2";
@Resource
......
package com.zksy.szpt;
import cn.hutool.crypto.digest.DigestUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zksy.szpt.domain.dto.SzptClockInDTO;
import com.zksy.szpt.service.AppStoreService;
import com.zksy.szpt.util.EncryptUtil;
import com.zksy.szpt.util.SignatureUtil;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import javax.annotation.Resource;
@SpringBootTest()
public class MainTestX {
String nonce = "2";
String timestampStr = "21";
String appId = "1872576325743943682";
@Resource
private ObjectMapper objectMapper;
@Resource
private AppStoreService appStoreService;
/**
* 任务完成情况
*/
@Test
@DisplayName("考勤")
public void szptClockInTest() {
timestampStr = String.valueOf(System.currentTimeMillis() / 1000);
nonce = String.valueOf(System.currentTimeMillis() / 1000);
String secretKey = this.appStoreService.getAppSecretByAppKey(appId);
Assertions.assertNotNull(secretKey, "appId不存在");//断言appId存在,为空直接抛出异常不进行下一步测试,提高测试效率
//请求参数
SzptClockInDTO szptClockInDTO = new SzptClockInDTO();
szptClockInDTO.setId(100);
szptClockInDTO.setCsid("123456");
szptClockInDTO.setSbqd("123456");
szptClockInDTO.setXbqt("123456");
szptClockInDTO.setXcqk("1");
szptClockInDTO.setSbsj("1");
szptClockInDTO.setSbr("123456");
szptClockInDTO.setQdr("123456");
szptClockInDTO.setQdrlxdh("123456");
szptClockInDTO.setQddkdd("1");
szptClockInDTO.setQddkzp("1");
szptClockInDTO.setQtdkdd("1");
szptClockInDTO.setQtdkzp("1");
szptClockInDTO.setGkdj("1");
String json = null;
try {
json = objectMapper.writeValueAsString(szptClockInDTO);
} catch (JsonProcessingException e) {
Assertions.fail("json序列化失败");
}
//请求体加密
json = EncryptUtil.getInstance().AESEncode(json, secretKey);
//签名appId+nonce+timestampStr+aes(body)
String data = String.format("%s%s%s%s", appId, nonce, timestampStr, json);
String generatedSignature = DigestUtil.md5Hex(data);
//请求
WebClient webClient = WebClient.builder()
.baseUrl("http://localhost:8086")
.defaultHeader("Content-Type", "application/json")
.build();
String response = webClient.post().uri("/rest/index/addSzptClockIn")
.header(SignatureUtil.APPID, appId)
.header(SignatureUtil.NONCE, nonce)
.header(SignatureUtil.TIMESTAMP, timestampStr)
.header(SignatureUtil.SIGNATURE, generatedSignature)
.body(Mono.just(szptClockInDTO), SzptClockInDTO.class)
.retrieve()
.bodyToMono(String.class)
.block();
System.out.println(response);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment