需求:每一个请求都需要签名认证,即在外部请求的过程中需要在URI末尾?后加上key=value形式的参数Query Param
Query Param : timestamp,nonce_str,sign(timestamp:时间戳;noce_str:随机字符串;sign:appid×tamp&nonce_str&appsecret通过sha256加密获得字符串)
例:https://生产环境/test?timestamp=nonce_str=sign=
@Documented
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequireSignature {
}
@Component
public class ExternalServiceInterceptor extends HandlerInterceptorAdapter {
private Logger logger = LoggerFactory.getLogger(getClass());
private static final String appid = "1646464644654646";
private static final String appsecret = "ajgddqndqkdqbdqn";
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Method method = ((HandlerMethod) handler).getMethod();
if (AnnotatedElementUtils.isAnnotated(method, RequireSignature.class)) {
long now = System.currentTimeMillis();
String timestamp = request.getParameter("timestamp");
Long timestampGain = Long.parseLong(timestamp);
if (Math.abs(now - timestampGain) > 3_000_000) {
logger.error("签名时间[" + timestampGain + "]已经过期,请重试!");
throw new BadRequestException("签名已经过期,请重试!");
}
String nonce_str = request.getParameter("nonce_str");
String signGain = request.getParameter("sign");
if (nonce_str.isEmpty() || signGain.isEmpty()) {
logger.error("签名不存在,请稍后重试!");
throw new BadRequestException("签名不存在,请稍后重试!");
}
String sign = DigestUtils.sha256Hex(appid + "&"+ timestamp + "&" + nonce_str + "&" + appsecret).toLowerCase();
if (!signGain.equals(sign)) {
logger.error("签名sign [ " + signGain + " ] 错误!");
throw new BadRequestException("签名sign [ " + signGain + " ] 错误!");
}
}
return super.preHandle(request, response, handler);
}
}
在需要签名验证的请求接口上加上@RequireSignature注解即可
@RequireSignature
@RequestMapping(value = "test",method = RequestMethod.GET)
public JSONObject getKey(){
return testService.getKey();
}
}