接口签名

import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;

/**
 * @description: 接口鉴权
 * @author: DXM
 **/
@Component
public class APIFilter extends OncePerRequestFilter {

    // 固定参数名
    private final String APP_ID = "APP_ID";              // 调用方标识
    private final String APP_SECRET = "APP_SECRET";     // 调用方标识
    private final String TIME_STAMP = "TIME_STAMP";     // 时间戳
    private final String SIGN = "SIGN";                   // 客户端签名
    private final String NONCE = "NONCE";                 // 流水号
    private final String REQ_URL = "REQ_URL";            // URL

    private final Map<String, String> id_secret = new HashMap<>();

    public APIFilter() {
        id_secret.put("1001", SecureUtil.md5("API1001"));
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
        String uri = request.getRequestURI();
        if (uri.endsWith(".html") || uri.endsWith(".css") || uri.endsWith(".js") || uri.endsWith(".png") || uri.endsWith("ui") || uri.startsWith("/swagger-resources") || uri.startsWith("/webjars") || uri.startsWith("/v2") || uri.startsWith("/csrf")) {
            chain.doFilter(request, response);
            return;
        }

        System.out.println(uri);

        // 非空及时间验证
        String verify = verifyHeaderParams(request);
        if (StringUtils.isEmpty(verify)) {
            verify = verifySign(request);
        }

        if (!StringUtils.isEmpty(verify)) {
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json;charset=UTF-8");
            PrintWriter pw = response.getWriter();
            JSONObject jo = new JSONObject();
            jo.set("success", false);
            jo.set("msg", verify);
            pw.append(jo.toJSONString(0));
        } else {
            chain.doFilter(request, response);
        }
    }

    private String verifySign(HttpServletRequest request) {
        Map<String, String> signMap = new HashMap<>();
        signMap.put(APP_ID, request.getHeader(APP_ID));
        signMap.put(APP_SECRET, id_secret.get(request.getHeader(APP_ID)));
        signMap.put(TIME_STAMP, request.getHeader(TIME_STAMP));
        signMap.put(NONCE, request.getHeader(NONCE));
        String url = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getServletPath();
        signMap.put(REQ_URL, url);
        List<String> keyList = new ArrayList<>(signMap.keySet());
        Collections.sort(keyList);
        StringBuffer signStr = new StringBuffer();
        for (String k : keyList) {
            signStr.append(k + "=" + signMap.get(k));
        }
        String clientSign = request.getHeader(SIGN);
        String serverSign = SecureUtil.md5(signStr.toString());
        if (clientSign.equals(serverSign)) {
            return null;
        }
        return "签名失败!";
    }

    private String verifyHeaderParams(HttpServletRequest request) {
        String appID = request.getHeader(APP_ID);
        String timeStamp = request.getHeader(TIME_STAMP);
        String sign = request.getHeader(SIGN);
        String nonce = request.getHeader(NONCE);
        if (StringUtils.isEmpty(appID)) {
            return APP_ID + "不能为空!";
        }
        if (StringUtils.isEmpty(id_secret.get(appID))) {
            return APP_ID + "不存在!";
        }
        if (StringUtils.isEmpty(timeStamp)) {
            return TIME_STAMP + "不能为空!";
        }
        if (StringUtils.isEmpty(sign)) {
            return SIGN + "不能为空!";
        }
        if (StringUtils.isEmpty(nonce)) {
            return NONCE + "不能为空!";
        }
        System.out.println(System.currentTimeMillis());
        long diff = System.currentTimeMillis() - Long.parseLong(timeStamp);
        if (Math.abs(diff) > 10 * 60 * 1000) {
            return TIME_STAMP + "超时!";
        }
        return null;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值