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