詳解Java接口簽名(Signature)實(shí)現(xiàn)方案
大家好,我是程序員田同學(xué)!
今天上午收到一個(gè)需求,針對(duì)當(dāng)前的系統(tǒng)開發(fā)一個(gè)對(duì)外開放的接口。
既然是對(duì)外開放,那么調(diào)用者一定沒有我們系統(tǒng)的Token,就需要對(duì)調(diào)用者進(jìn)行簽名驗(yàn)證,簽名驗(yàn)證采用主流的驗(yàn)證方式,采用Signature 的方式。
一、要求
下圖為具體要求

二、流程
?1、線下分配appid和appsecret,針對(duì)不同的調(diào)用方分配不同的appid和appsecret
2、加入timestamp(時(shí)間戳),10分鐘內(nèi)數(shù)據(jù)有效
3、加入流水號(hào)noncestr(防止重復(fù)提交),至少為10位。針對(duì)查詢接口,流水號(hào)只用于日志落地,便于后期日志核查。 針對(duì)辦理類接口需校驗(yàn)流水號(hào)在有效期內(nèi)的唯一性,以避免重復(fù)請(qǐng)求。
4、加入signature,所有數(shù)據(jù)的簽名信息。

三、實(shí)現(xiàn)
簡單來說,調(diào)用者調(diào)用接口業(yè)務(wù)參數(shù)在body中傳遞,header中額外增加四個(gè)參數(shù)signature、appkey、timestamp、noncestr。
我們?cè)诤笈_(tái)取到四個(gè)參數(shù),其后三個(gè)參數(shù)加上調(diào)用者分配的appSecret,使用字典排序并使用MD5加密后與第一個(gè)參數(shù)signature進(jìn)行比對(duì),一致既表示調(diào)用者有權(quán)限調(diào)用。
以下代碼為接口驗(yàn)證簽名的demo實(shí)現(xiàn):
//引用jackson依賴
@Autowired
private ObjectMapper objectMapper;
@Value("${appsecret}")
private String appSecret;
/**
* 驗(yàn)證簽名
* @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);
//因?yàn)樾枰判?,直接使用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);
//簽名比對(duì)
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("對(duì)象轉(zhuǎn)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轉(zhuǎn)json異常");
}
return s2;
}到此這篇關(guān)于Java接口簽名(Signature)實(shí)現(xiàn)方案 的文章就介紹到這了,更多相關(guān)Java接口簽名內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
ActiveMQ結(jié)合Spring收發(fā)消息的示例代碼
這篇文章主要介紹了ActiveMQ結(jié)合Spring收發(fā)消息的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-10-10
java構(gòu)建Stream流的多種方式總結(jié)
Java?8引入了Stream流作為一項(xiàng)新的特性,它是用來處理集合數(shù)據(jù)的一種函數(shù)式編程方式,本文為大家整理了多種java構(gòu)建Stream流的方式,希望對(duì)大家有所幫助2023-11-11
SpringBoot2.0集成Swagger2訪問404的解決操作
這篇文章主要介紹了SpringBoot2.0集成Swagger2訪問404的解決操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-09-09
java文件重命名(文件批量重命名)實(shí)例程序代碼分享
這篇文章主要介紹了java文件重命名的程序代碼,大家參考使用吧2013-12-12
使用Post方式提交數(shù)據(jù)到Tomcat服務(wù)器的方法
這篇將介紹使用Post方式提交數(shù)據(jù)到服務(wù)器,由于Post的方式和Get方式創(chuàng)建Web工程是一模一樣的,只用幾個(gè)地方的代碼不同,這篇文章主要介紹了使用Post方式提交數(shù)據(jù)到Tomcat服務(wù)器的方法,感興趣的朋友一起學(xué)習(xí)吧2016-04-04

