詳解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; }
到此這篇關於Java接口簽名(Signature)實現方案 的文章就介紹到這瞭,更多相關Java接口簽名內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Spring Boot 實現敏感詞及特殊字符過濾處理
- Java循環對bean的屬性進行賦值的實現
- Java反射,泛型在Json中的運用
- python註冊釘釘回調事件的實現
- Java如何比較兩個對象並獲取不相等的字段詳解