Java介面簽名(Signature)實作方案
大家好,我是程式員田同學!
今天上午收到一個需求,針對當前的系統開發一個對外開放的介面,
既然是對外開放,那么呼叫者一定沒有我們系統的Token,就需要對呼叫者進行簽名驗證,簽名驗證采用主流的驗證方式,采用Signature 的方式,
一、要求
下圖為具體要求

二、流程
? 1、線下分配appid和appsecret,針對不同的呼叫方分配不同的appid和appsecret
2、加入timestamp(時間戳),10分鐘內資料有效
3、加入流水號noncestr(防止重復提交),至少為10位,針對查詢介面,流水號只用于日志落地,便于后期日志核查, 針對辦理類介面需校驗流水號在有效期內的唯一性,以避免重復請求,
4、加入signature,所有資料的簽名資訊,

三、實作
簡單來說,呼叫者呼叫介面業務引數在body中傳遞,header中額外增加四個引數signature、appkey、timestamp、noncestr,
我們在后臺取到四個引數,其后三個引數加上呼叫者分配的appSecret,使用字典排序并使用MD5加密后與第一個引數signature進行比對,一致既表示呼叫者有權限呼叫,
以下代碼為介面驗證簽名的demo實作:
//參考jackson依賴
@Autowired
private ObjectMapper objectMapper;
@Value("${appsecret}")
private String appSecret;
/**
* 驗證簽名
* @param preInfoItem
* @return
*/
boolean checkSignature(PreInfoItem preInfoItem) throws JsonProcessingException, IllegalAccessException {
String signature="signature";
String appkey="appkey";
String timestamp="timestamp";
String noncestr="noncestr";
HttpServletRequest request = ServletUtils.getRequest();
String headerSignature = request.getHeader(signature);
String headerAppkey = request.getHeader(appkey);
String headerTimestamp = request.getHeader(timestamp);
String headerNoncestr = request.getHeader(noncestr);
//因為需要排序,直接使用TreeMap
Map<String,Object> parms=new TreeMap<>();
parms.put(appkey,headerAppkey);
parms.put(timestamp,headerTimestamp);
parms.put(noncestr,headerNoncestr);
Map<String, Object> stringObjectMap = objectToMap(parms, preInfoItem);
String s = buildSignature(stringObjectMap);
//簽名比對
if (s.equals(headerSignature)){
return true;
}
return false;
}
Map<String,Object> objectToMap(Map<String,Object> map,Object o){
Field[] declaredFields = o.getClass().getDeclaredFields();
for (Field field : declaredFields) {
field.setAccessible(true);
try {
if (field.getName() instanceof String){
map.put(field.getName(),field.get(o));
}
}catch (IllegalAccessException e){
throw new CustomException("物件轉map例外");
}
}
return map;
}
private String buildSignature(Map<String,Object> maps){
String s2;
try {
StringBuffer s = null;
String s1 = objectMapper.writeValueAsString(maps);
//添加appSecret
s.append(s1).append(appSecret);
s2 = DigestUtils.md5DigestAsHex(s.toString().getBytes());
}catch (JsonProcessingException e){
throw new CustomException("map轉json例外");
}
return s2;
}
好啦,趕快去試一下吧!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/415238.html
標籤:其他
下一篇:druid資料庫連接池的配置類
