簡單的接口簽名認證

 

public void addInterceptors(InterceptorRegistry registry) {
  //接口簽名認證攔截器,該簽名認證比較簡單,實際項目中可以使用Json Web Token或其他更好的方式替代。
  if (!"dev".equals(env)) { //開發環境忽略簽名認證
      registry.addInterceptor(new HandlerInterceptorAdapter() {
          @Override
          public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
              //驗證簽名
              boolean pass = validateSign(request);
              if (pass) {
                  return true;
              } else {
                  logger.warn("簽名認證失敗,請求接口:{},請求IP:{},請求參數:{}",
                          request.getRequestURI(), getIpAddress(request), JSON.toJSONString(request.getParameterMap()));

                  Result result = new Result();
                  result.setCode(ResultCode.UNAUTHORIZED).setMessage("簽名認證失敗");
                  responseResult(response, result);
                  return false;
              }
          }
      });
  }
}
/**
* 一個簡單的簽名認證,規則:
* 1. 將請求參數按ascii碼排序
* 2. 拼接爲a=value&b=value...這樣的字符串(不包含sign)
* 3. 混合密鑰(secret)進行md5獲得簽名,與請求的簽名進行比較
*/
private boolean validateSign(HttpServletRequest request) {
      String requestSign = request.getParameter("sign");//獲得請求籤名,如sign=19e907700db7ad91318424a97c54ed57
      if (StringUtils.isEmpty(requestSign)) {
          return false;
      }
      List<String> keys = new ArrayList<String>(request.getParameterMap().keySet());
      keys.remove("sign");//排除sign參數
      Collections.sort(keys);//排序

      StringBuilder sb = new StringBuilder();
      for (String key : keys) {
          sb.append(key).append("=").append(request.getParameter(key)).append("&");//拼接字符串
      }
      String linkString = sb.toString();
      linkString = StringUtils.substring(linkString, 0, linkString.length() - 1);//去除最後一個'&'

      String secret = "Potato";//密鑰,自己修改
      String sign = DigestUtils.md5Hex(linkString + secret);//混合密鑰md5

      return StringUtils.equals(sign, requestSign);//比較
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章