|
@@ -0,0 +1,159 @@
|
|
|
+package cn.com.qmth.examcloud.exchange.config;
|
|
|
+
|
|
|
+import javax.servlet.http.HttpServletRequest;
|
|
|
+import javax.servlet.http.HttpServletResponse;
|
|
|
+
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.springframework.http.HttpStatus;
|
|
|
+import org.springframework.web.servlet.HandlerInterceptor;
|
|
|
+import org.springframework.web.servlet.ModelAndView;
|
|
|
+
|
|
|
+import cn.com.qmth.examcloud.commons.base.exception.StatusException;
|
|
|
+import cn.com.qmth.examcloud.commons.base.logging.ExamCloudLog;
|
|
|
+import cn.com.qmth.examcloud.commons.base.logging.ExamCloudLogFactory;
|
|
|
+import cn.com.qmth.examcloud.commons.base.util.ByteUtil;
|
|
|
+import cn.com.qmth.examcloud.commons.base.util.SHA256;
|
|
|
+import cn.com.qmth.examcloud.commons.base.util.StringUtil;
|
|
|
+import cn.com.qmth.examcloud.commons.web.redis.RedisClient;
|
|
|
+import cn.com.qmth.examcloud.commons.web.support.ServletUtil;
|
|
|
+import cn.com.qmth.examcloud.commons.web.support.StatusResponseEntity;
|
|
|
+import cn.com.qmth.examcloud.core.basic.api.CommonCloudService;
|
|
|
+import cn.com.qmth.examcloud.core.basic.api.bean.ThirdPartyAccessBean;
|
|
|
+import cn.com.qmth.examcloud.core.basic.api.request.GetThirdPartyAccessInfoReq;
|
|
|
+import cn.com.qmth.examcloud.core.basic.api.response.GetThirdPartyAccessInfoResp;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 第三方请求接入
|
|
|
+ *
|
|
|
+ * @author WANGWEI
|
|
|
+ * @date 2018年5月22日
|
|
|
+ * @Copyright (c) 2018-? http://qmth.com.cn All Rights Reserved.
|
|
|
+ */
|
|
|
+public final class ThirdPartyAccessInterceptor implements HandlerInterceptor {
|
|
|
+
|
|
|
+ private static final ExamCloudLog LOG = ExamCloudLogFactory
|
|
|
+ .getLog(ThirdPartyAccessInterceptor.class);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 接口日志
|
|
|
+ */
|
|
|
+ protected static final ExamCloudLog INTERFACE_LOG = ExamCloudLogFactory
|
|
|
+ .getLog("INTERFACE_LOGGER");
|
|
|
+
|
|
|
+ /**
|
|
|
+ * redis client
|
|
|
+ */
|
|
|
+ private RedisClient redisClient;
|
|
|
+
|
|
|
+ private CommonCloudService commonCloudService;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
|
|
|
+ Object handler) throws Exception {
|
|
|
+ LOG.debug("preHandle... ...");
|
|
|
+
|
|
|
+ String accessToken = request.getHeader("access_token");
|
|
|
+ if (null == accessToken) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ String rootOrgId = request.getHeader("rootOrgId");
|
|
|
+ String appId = request.getHeader("appId");
|
|
|
+ String timestamp = request.getHeader("timestamp");
|
|
|
+
|
|
|
+ if (StringUtils.isBlank(rootOrgId) || StringUtils.isBlank(appId)
|
|
|
+ || StringUtils.isBlank(timestamp)) {
|
|
|
+ response.setStatus(HttpStatus.FORBIDDEN.value());
|
|
|
+ ServletUtil.returnJson(
|
|
|
+ new StatusResponseEntity("403",
|
|
|
+ "第三方接入请求必须包含请求头['access_token','rootOrgId','appId','timestamp']"),
|
|
|
+ response);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ accessToken = accessToken.trim();
|
|
|
+ rootOrgId = rootOrgId.trim();
|
|
|
+ appId = appId.trim();
|
|
|
+ timestamp = timestamp.trim();
|
|
|
+
|
|
|
+ if (!(StringUtil.isLong(rootOrgId) && StringUtil.isLong(timestamp))) {
|
|
|
+ response.setStatus(HttpStatus.FORBIDDEN.value());
|
|
|
+ ServletUtil.returnJson(
|
|
|
+ new StatusResponseEntity("403", "第三方接入请求头['rootOrgId','timestamp']必须是整数"),
|
|
|
+ response);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ String key = "A_" + rootOrgId + appId;
|
|
|
+
|
|
|
+ ThirdPartyAccessBean thirdPartyAccessBean = redisClient.get(key, ThirdPartyAccessBean.class,
|
|
|
+ 60000);
|
|
|
+
|
|
|
+ if (null == thirdPartyAccessBean) {
|
|
|
+ try {
|
|
|
+ thirdPartyAccessBean = getThirdPartyAccessInfo(rootOrgId, appId);
|
|
|
+ } catch (StatusException e) {
|
|
|
+ response.setStatus(HttpStatus.FORBIDDEN.value());
|
|
|
+ ServletUtil.returnJson(new StatusResponseEntity("403", e.getDesc()), response);
|
|
|
+ return false;
|
|
|
+ } catch (Exception e) {
|
|
|
+ response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
|
|
|
+ ServletUtil.returnJson(new StatusResponseEntity("500", "获取第三方接入信息异常"), response);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ redisClient.set(key, thirdPartyAccessBean, 60000);
|
|
|
+ }
|
|
|
+
|
|
|
+ long timestampLong = Long.parseLong(timestamp);
|
|
|
+
|
|
|
+ long currentTimeMillis = System.currentTimeMillis();
|
|
|
+ if (Math.abs(currentTimeMillis - timestampLong) > thirdPartyAccessBean.getTimeRange()) {
|
|
|
+ throw new StatusException("B-001203", "timestamp超出时间差范围");
|
|
|
+ }
|
|
|
+
|
|
|
+ String secretKey = thirdPartyAccessBean.getSecretKey();
|
|
|
+ String joinStr = StringUtil.join(rootOrgId, appId, timestamp, secretKey);
|
|
|
+ byte[] bytes = SHA256.encode(joinStr);
|
|
|
+ String hexAscii = ByteUtil.toHexAscii(bytes);
|
|
|
+
|
|
|
+ if (!hexAscii.equalsIgnoreCase(accessToken)) {
|
|
|
+ response.setStatus(HttpStatus.FORBIDDEN.value());
|
|
|
+ ServletUtil.returnJson(new StatusResponseEntity("403", "access_token校验失败"), response);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ request.setAttribute("$no_session_access", true);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ private ThirdPartyAccessBean getThirdPartyAccessInfo(String rootOrgId, String appId) {
|
|
|
+ ThirdPartyAccessBean thirdPartyAccessBean;
|
|
|
+ GetThirdPartyAccessInfoReq req = new GetThirdPartyAccessInfoReq();
|
|
|
+ req.setAppId(appId);
|
|
|
+ req.setRootOrgId(Long.parseLong(rootOrgId));
|
|
|
+ GetThirdPartyAccessInfoResp resp = commonCloudService.getThirdPartyAccessInfo(req);
|
|
|
+ thirdPartyAccessBean = resp.getThirdPartyAccessBean();
|
|
|
+ return thirdPartyAccessBean;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
|
|
|
+ ModelAndView modelAndView) throws Exception {
|
|
|
+ LOG.debug("postHandle... ...");
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
|
|
|
+ Object handler, Exception ex) throws Exception {
|
|
|
+ LOG.debug("afterCompletion... ...");
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setRedisClient(RedisClient redisClient) {
|
|
|
+ this.redisClient = redisClient;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setCommonCloudService(CommonCloudService commonCloudService) {
|
|
|
+ this.commonCloudService = commonCloudService;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|