对外接口加密

package com.yonyou.cyx.datacenter.service.filter;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.concurrent.TimeUnit;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RequestMethod;

import com.alibaba.fastjson.JSON;
import com.xiaoleilu.hutool.util.StrUtil;
import com.yonyou.cyx.cyxframework.util.MD5Util;
import com.yonyou.cyx.framework.bean.dto.framework.RestResultResponse;
import com.yonyou.cyx.framework.bean.dto.framework.ResultBean;

@WebFilter(urlPatterns = "/**/**", filterName = "ExosystemFilter")
public class ExosystemFilter implements Filter {

@Autowired
private StringRedisTemplate redisTemplate;

@Autowired
private Environment env;

/**
* 日志
*/
private static Logger logger = LoggerFactory.getLogger(ExosystemFilter.class);

@Override
public void init(FilterConfig filterConfig) throws ServletException {
logger.info("ExosystemFilter init!");
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
@SuppressWarnings("unchecked")
RestResultResponse<Integer> result = new RestResultResponse<Integer>().success(false);
result.setResultCode(ResultBean.VALID_FAILD);
response.setContentType("application/json;charset=UTF-8");
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
Charset utf8charset = Charset.forName("UTF-8");
try {
// 接口只支持post请求
if (RequestMethod.POST.name().equalsIgnoreCase(httpServletRequest.getMethod())) {
ServletRequest requestWrapper = new PostBodyRequestWrapper(httpServletRequest);
String body = HttpHelper.getBodyString(requestWrapper);
if (StrUtil.isBlank(body)) {
result.setErrMsg("RequestBody不能为空");
response.getOutputStream().write(JSON.toJSONString(result).getBytes(utf8charset));
return;
} else {
String appid = httpServletRequest.getHeader("appid");
String nonce = httpServletRequest.getHeader("nonce");
String occurtime = httpServletRequest.getHeader("occurtime");
String sign = httpServletRequest.getHeader("sign");
logger.info("签名认证参数,appid:{}, nonce:{}, occurtime:{}, sign:{}", appid, nonce, occurtime, sign);
if (StrUtil.isBlank(appid) || StrUtil.isBlank(nonce) || StrUtil.isBlank(occurtime)
|| StrUtil.isBlank(sign)) {
result.setErrMsg("认证失败,必须参数不能为空");
response.getOutputStream().write(JSON.toJSONString(result).getBytes(utf8charset));
return;
} else {
// 根据appId获取appKey
String appKey = env.getProperty("appKey." + appid);
// 不存在
if (StrUtil.isBlank(appKey)) {
// 认证失败
result.setResultCode(401);
result.setErrMsg("认证失败,appId不合法");
response.getOutputStream()
.write(JSON.toJSONString(result).getBytes(utf8charset));
return;
}
// 生成签名
String signLocal = appKey + nonce + occurtime;
logger.info("加密前签名:" ,signLocal);
signLocal = MD5Util.md5(signLocal).toLowerCase();
logger.info("加密后签名:" ,signLocal);
if (signLocal.equals(sign)) {
String oldSign = redisTemplate.opsForValue().get(appid + sign);
// 判断签名是否重复调用
if (StrUtil.isNotBlank(oldSign)) {
result.setResultCode(401);
result.setErrMsg("认证失败,签名重复使用");
response.getOutputStream()
.write(JSON.toJSONString(result).getBytes(utf8charset));
return;
} else {
// 保存认证签名
logger.debug("请求签名:{}", sign);
redisTemplate.opsForValue().set(appid + sign, sign, 24 * 3600L, TimeUnit.SECONDS);
}
} else {
result.setResultCode(401);
result.setErrMsg("认证失败,签名加密错误");
response.getOutputStream()
.write(JSON.toJSONString(result).getBytes(utf8charset));
return;
}
}
chain.doFilter(requestWrapper, response);
}
} else {
result.setErrMsg("API只支持POST请求");
response.getOutputStream().write(JSON.toJSONString(result).getBytes(utf8charset));
return;
}
} catch (Exception e) {
logger.error("API认证失败:", e);
result.setErrMsg("认证失败," + e.getMessage());
response.getOutputStream().write(JSON.toJSONString(result).getBytes(utf8charset));
return;
}
}

@Override
public void destroy() {

}

public static void main(String[] args) throws InterruptedException, NoSuchAlgorithmException, UnsupportedEncodingException {
long time = new Date().getTime();
String nonce = "4465";
String sign = "0sTUkoug6HneoxFkJjGc_EYJ5WIIBcCD" + nonce + time;
// System.out.println(nonce);
// System.out.println(time);
// System.out.println(sign);
// System.out.println(MD5Util.md5(sign).toLowerCase());
}
}
原文地址:https://www.cnblogs.com/jabez1992/p/11339447.html