接口加签方案

场景:外部系统需要直接通过http方式调用内部系统的接口获取数据

方案:创建新的controller,将controller的映射地址配置在新建的interceptor(拦截器)中,使得拦截器能拦截到访问该controller的地址,在拦截器中做接口加签的合法性验证:

        //获取请求方的各种信息进行后续的验证使用

        url = acquireURL(request);
        timestamp = request.getHeader("X-Timestamp");
        nonce = request.getHeader("X-Nonce");
        appKey = request.getHeader("X-Appkey");
        signature = request.getHeader("X-Signature");
        body = acquireBody(request);

@Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
        AuthEntity entity = new AuthEntity(request);
        LOGGER.info("验签字符串:" + entity.toString());
        if (checkRequired(entity)//验证必填字段非空
                && checkTimestamp(entity.getTimestamp())//request header中传输的时间戳,用于验证发起的接口是否已经过期,和系统当前时间比较后得出,暂时是超过1小时算过期
                && checkNonce(entity.getNonce())//request header中传输的UUID,防止接口重复调用,从redis中获取该值是否为null来判断是否重复提交
                && SignatureUtil.checkSignature(entity)) {//根据头标签所有属性和报文内容再加密钥生成签名判断报文内容是否被篡改
            redisTemplate.opsForValue().set(entity.getNonce(), "1", EXPIRE_TIME+5, TimeUnit.SECONDS);//使用redis保存UUID并设置过期时间
            return true;
        }
        response.setStatus(401); // Unauthorized
        return false;
    }

签名生成方法:

    private static String generateSignature(String data, String secret) {
        byte[] result = null;
        try {
            SecretKeySpec signinKey = new SecretKeySpec(secret.getBytes("utf-8"), HMAC_SHA1_ALGORITHM);
            Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);
            mac.init(signinKey);
            byte[] rawHmac = mac.doFinal(data.getBytes("utf-8"));
            result = Base64.encodeBase64(rawHmac);
            return new String(result,"utf-8");
        } catch (InvalidKeyException | NoSuchAlgorithmException | UnsupportedEncodingException e) {
            LOGGER.error(e.toString());
        }
        return null;
    }

转载于:https://my.oschina.net/ffse54s/blog/3045941

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值