| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300 |
- package com.zswl.dataservice.service.openApi;
- import cn.hutool.json.JSONObject;
- import cn.hutool.json.JSONUtil;
- import com.zswl.dataservice.auth.OpenAPIContext;
- import com.zswl.dataservice.dao.openApi.BlackListDao;
- import com.zswl.dataservice.dao.openApi.OpenApiRequestLogDao;
- import com.zswl.dataservice.dao.openApi.OpenApiSignInfoDao;
- import com.zswl.dataservice.dataConfig.OpenAPIConfig;
- import com.zswl.dataservice.domain.openApi.OpenApiRequestLog;
- import com.zswl.dataservice.domain.openApi.OpenApiSignInfo;
- import com.zswl.dataservice.service.base.RedisService;
- import com.zswl.dataservice.service.user.OperationLogsService;
- import com.zswl.dataservice.type.OperationLogType;
- import com.zswl.dataservice.utils.AesUtils;
- import com.zswl.dataservice.utils.DateUtils;
- import com.zswl.dataservice.utils.HttpUtils;
- import com.zswl.dataservice.utils.mqtt.type.LogsLevel;
- import com.zswl.dataservice.utils.net.IPUtil;
- import com.zswl.dataservice.utils.os.SystemUtil;
- import com.zswl.dataservice.utils.result.ResultContent;
- import jakarta.servlet.ServletInputStream;
- import jakarta.servlet.ServletOutputStream;
- import jakarta.servlet.http.HttpServletRequest;
- import jakarta.servlet.http.HttpServletResponse;
- import lombok.Data;
- import lombok.SneakyThrows;
- import lombok.extern.slf4j.Slf4j;
- import org.apache.commons.lang3.ObjectUtils;
- import org.apache.commons.lang3.StringUtils;
- import org.aspectj.apache.bcel.classfile.Module;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.context.ApplicationContext;
- import org.springframework.http.HttpStatus;
- import org.springframework.stereotype.Service;
- import org.springframework.web.context.request.RequestContextHolder;
- import org.springframework.web.context.request.ServletRequestAttributes;
- import org.springframework.web.servlet.ModelAndView;
- import org.springframework.web.util.ContentCachingRequestWrapper;
- import org.springframework.web.util.ContentCachingResponseWrapper;
- import java.io.BufferedReader;
- import java.io.InputStreamReader;
- import java.io.OutputStream;
- import java.io.PrintWriter;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- import java.util.concurrent.TimeUnit;
- /**
- * @author TRX
- * @date 2024/9/11
- */
- @Slf4j
- @Service
- public class OpenApiVerifyService {
- @Autowired
- private RedisService redisService;
- @Autowired
- private OpenApiRequestLogsService openApiRequestLogsService;
- @Autowired
- private OpenApiRequestLogDao openApiRequestLogDao;
- @Autowired
- OperationLogsService operationLogsService;
- @Autowired
- BlackListDao blackListDao;
- @Autowired
- OpenApiSignInfoDao openApiSignInfoDao;
- //线程池
- ExecutorService executorService = Executors.newFixedThreadPool(SystemUtil.getCpuCoreCount() * 2);
- @Autowired
- private void init(ApplicationContext applicationContext) {
- Runtime.getRuntime().addShutdownHook(new Thread(() -> {
- executorService.shutdownNow();
- }));
- }
- /**
- * 验证OpenAPI preHandle
- *
- * @param request
- * @param response
- * @param object
- * @return
- */
- @SneakyThrows
- public boolean verifyOpenAPI(HttpServletRequest request, HttpServletResponse response, Object object) {
- log.info("---------------------openAPI验证----------------------");
- OpenAPIContext.setTime(System.currentTimeMillis());
- if (request instanceof ContentCachingRequestWrapper) {
- ContentCachingRequestWrapper contentCachingRequestWrapper = (ContentCachingRequestWrapper) request;
- ContentCachingResponseWrapper responseWrapper = (ContentCachingResponseWrapper) response;
- String requestStr = contentCachingRequestWrapper.getContentAsString();
- String msg = "认证错误";
- int code = 403;
- boolean isSuccess = false;
- if (contentCachingRequestWrapper.getContentLength() > OpenAPIConfig.maxLen) {
- setResponse(request, responseWrapper, "请求内容过大", 403, false);
- return false;
- }
- log.info("请求数据requestStr: {}", requestStr);
- String authorization = request.getHeader("authorization");
- log.info("authorization数据 {}", authorization);
- if (StringUtils.isNotEmpty(authorization)) {
- if (authorization.length() > OpenAPIConfig.maxLen) {
- setResponse(request, responseWrapper, "请求内容过大", 403, false);
- return false;
- }
- authorization = authorization.replaceAll(" ", "");
- if (authorization.startsWith(OpenAPIConfig.OPENBODYSIG)) {
- authorization = authorization.replace(OpenAPIConfig.OPENBODYSIG, "");
- HashMap<String, String> map = new HashMap<>();
- String[] arr = authorization.split(",");
- isSuccess = true;
- if (arr.length > 0) {
- for (String s : arr) {
- for (String key : OpenAPIConfig.authKeys) {
- if (s.startsWith(key)) {
- String val = s.replace(key + "=", "");
- val = val.replace("\"", "");
- map.put(key, val);
- break;
- }
- }
- }
- }
- if (isSuccess) {
- OpenApiSignInfo signInfo = null;
- if (!map.containsKey("AppId")) {
- isSuccess = false;
- msg = "没有AppId信息";
- }
- String appId = map.get("AppId");
- signInfo = openApiSignInfoDao.findTopByAppId(appId);
- if (ObjectUtils.isEmpty(signInfo)) {
- isSuccess = false;
- msg = "AppId错误";
- }
- if (isSuccess && !map.containsKey("Timestamp")) {
- isSuccess = false;
- msg = "没有Timestamp信息";
- }
- String timestamp = map.get("Timestamp");
- if (StringUtils.isEmpty(timestamp) || timestamp.length() != 14) {
- isSuccess = false;
- msg = "Timestamp格式错误";
- }
- if (isSuccess){
- Long time = DateUtils.timeToLong(timestamp, DateUtils.unionAuth);
- if (time == null || Math.abs(time - System.currentTimeMillis()) > OpenAPIConfig.timeBetween) {
- isSuccess = false;
- msg = "Timestamp不符合要求";
- }
- }
- if (isSuccess && !map.containsKey("Nonce")) {
- isSuccess = false;
- msg = "没有Nonce信息";
- }
- String nonce = map.get("Nonce");
- if (isSuccess && (StringUtils.isEmpty(nonce) || nonce.length() > 50)) {
- isSuccess = false;
- msg = "Nonce为空或长度不符合要求";
- }
- if (isSuccess && !map.containsKey("Signature")) {
- isSuccess = false;
- msg = "没有Signature信息";
- }
- String signature = map.get("Signature");
- if (isSuccess && (StringUtils.isEmpty(signature) || signature.length() > 200)) {
- isSuccess = false;
- msg = "Signature为空或长度不符合要求";
- }
- if(isSuccess) {
- String sign = AesUtils.signData(requestStr);
- log.info("数据sign {}", sign);
- String appKey = signInfo.getAppKey();
- String c = String.format("%s%s%s%s", appId, timestamp, nonce, sign);
- String tempSignature = AesUtils.signMacSHA256(c, appKey);
- log.info("系统tempSignature {}", tempSignature);
- log.info("传入signature {}", signature);
- if (!tempSignature.equals(signature)) {
- isSuccess = false;
- msg = "Signature认证错误";
- }
- }
- }
- } else {
- msg = "报文头没有OPEN-BODY-SIG标记";
- }
- } else {
- msg = "报文头authorization为空";
- }
- if (!isSuccess) {
- // 验证不成功
- setResponse(request, responseWrapper, msg, code, true);
- return false;
- }
- }
- return true;
- }
- /**
- * 记录日志 postHandle
- *
- * @param request
- * @param response
- * @param handler
- * @param modelAndView
- */
- @SneakyThrows
- public void saveOpenAPILog(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
- ResultContent resultContent = null;
- if (response instanceof ContentCachingResponseWrapper) {
- ContentCachingResponseWrapper responseWrapper = (ContentCachingResponseWrapper) response;
- byte[] bytes = responseWrapper.getContentAsByteArray();
- resultContent = HttpUtils.toBean(new String(bytes), ResultContent.class);
- responseWrapper.copyBodyToResponse();
- }
- saveLog(request, resultContent);
- }
- public boolean isInBlackList(HttpServletRequest request) {
- String ip = IPUtil.getRemoteIp(request);
- if (blackListDao.existsByIp(ip)) {
- ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
- RequestContextHolder.setRequestAttributes(servletRequestAttributes, true);//设置子线程共享
- executorService.execute(() -> {
- operationLogsService.addLogs(String.format("黑名单地址访问: %s", ip), LogsLevel.High, OperationLogType.Black, null);
- });
- return true;
- }
- return false;
- }
- @SneakyThrows
- private void setResponse(HttpServletRequest request, ContentCachingResponseWrapper responseWrapper, String msg, int code, boolean isSaveLog) {
- ResultContent resultContent = ResultContent.buildFail(msg, code);
- responseWrapper.setCharacterEncoding("UTF-8");
- responseWrapper.setHeader("Content-Type", "application/json");
- responseWrapper.setStatus(HttpStatus.PAYMENT_REQUIRED.value());
- PrintWriter printWriter = responseWrapper.getWriter();
- printWriter.write(JSONUtil.toJsonStr(resultContent));
- printWriter.flush();
- printWriter.close();
- responseWrapper.copyBodyToResponse();
- if (isSaveLog) {
- saveLog(request, resultContent);
- }
- resultContent = null;
- }
- private void saveLog(HttpServletRequest request, ResultContent resultContent) {
- OpenApiRequestLog openApiRequestLog = new OpenApiRequestLog();
- JSONObject param = HttpUtils.getRequestObj(request);
- if (param != null) {
- openApiRequestLog.setRequestBody(param);
- openApiRequestLog.setAppId(param.getStr("appId"));
- }
- Long startTime = OpenAPIContext.getTime();
- openApiRequestLog.setResponseTime(System.currentTimeMillis());
- if (startTime != null) {
- openApiRequestLog.setRequestTime(startTime);
- openApiRequestLog.setRequestTimeStr(DateUtils.paresTime(startTime, DateUtils.FORMAT_LONG));
- openApiRequestLog.setUserTime(System.currentTimeMillis() - startTime);
- }
- try {
- openApiRequestLog.setUa(request.getHeader("User-Agent"));
- openApiRequestLog.setIp(IPUtil.getRemoteIp(request));
- openApiRequestLog.setUrl(request.getRequestURI());
- } catch (Exception e) {
- e.printStackTrace();
- }
- openApiRequestLog.setAuthorization(request.getHeader("authorization"));
- openApiRequestLog.setTTL(new Date(System.currentTimeMillis() + OpenAPIConfig.logTTL));
- if (resultContent != null) {
- openApiRequestLog.setIsSuccess(resultContent.isSuccess());
- openApiRequestLog.setErrorMsg(resultContent.getMsg());
- }
- openApiRequestLog.setResponseBody(resultContent);
- openApiRequestLogDao.save(openApiRequestLog);
- }
- }
|