关于java:Java接口签名Signature实现方案

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;
    }

好啦,赶快去试一下吧!

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理