|
@@ -1,164 +1,164 @@
|
|
|
-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.cloud.api.OuterService;
|
|
|
-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.StatusResponse;
|
|
|
-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... ...");
|
|
|
-
|
|
|
- Class<?> ctrClass = (Class<?>) request.getAttribute("$ctrClass");
|
|
|
- if (!OuterService.class.isAssignableFrom(ctrClass)) {
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- String accessToken = request.getHeader("access_token");
|
|
|
- String rootOrgId = request.getHeader("rootOrgId");
|
|
|
- String appId = request.getHeader("appId");
|
|
|
- String timestamp = request.getHeader("timestamp");
|
|
|
-
|
|
|
- if (StringUtils.isBlank(accessToken) || StringUtils.isBlank(rootOrgId)
|
|
|
- || StringUtils.isBlank(appId) || StringUtils.isBlank(timestamp)) {
|
|
|
- response.setStatus(HttpStatus.FORBIDDEN.value());
|
|
|
- ServletUtil.returnJson(
|
|
|
- new StatusResponse("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 StatusResponse("403", "第三方接入请求头['rootOrgId','timestamp']必须是整数"), response);
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- request.setAttribute("$rootOrgId", Long.parseLong(rootOrgId));
|
|
|
-
|
|
|
- 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 StatusResponse("403", e.getDesc()), response);
|
|
|
- return false;
|
|
|
- } catch (Exception e) {
|
|
|
- response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
|
|
|
- ServletUtil.returnJson(new StatusResponse("500", "获取第三方接入信息异常"), response);
|
|
|
- return false;
|
|
|
- }
|
|
|
- redisClient.set(key, thirdPartyAccessBean, 60000);
|
|
|
- }
|
|
|
-
|
|
|
- if (null != thirdPartyAccessBean.getTimeRange()) {
|
|
|
- long timestampLong = Long.parseLong(timestamp);
|
|
|
- long currentTimeMillis = System.currentTimeMillis();
|
|
|
- if (Math.abs(currentTimeMillis - timestampLong) > thirdPartyAccessBean.getTimeRange()) {
|
|
|
- response.setStatus(HttpStatus.FORBIDDEN.value());
|
|
|
- ServletUtil.returnJson(new StatusResponse("403", "timestamp超出时间差范围"), response);
|
|
|
- return false;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- 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 StatusResponse("403", "access_token校验失败"), response);
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- 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;
|
|
|
- }
|
|
|
-
|
|
|
-}
|
|
|
+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.cloud.api.OuterService;
|
|
|
+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.StatusResponse;
|
|
|
+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... ...");
|
|
|
+
|
|
|
+ Class<?> ctrClass = (Class<?>) request.getAttribute("$ctrClass");
|
|
|
+ if (!OuterService.class.isAssignableFrom(ctrClass)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ String accessToken = request.getHeader("access_token");
|
|
|
+ String rootOrgId = request.getHeader("rootOrgId");
|
|
|
+ String appId = request.getHeader("appId");
|
|
|
+ String timestamp = request.getHeader("timestamp");
|
|
|
+
|
|
|
+ if (StringUtils.isBlank(accessToken) || StringUtils.isBlank(rootOrgId)
|
|
|
+ || StringUtils.isBlank(appId) || StringUtils.isBlank(timestamp)) {
|
|
|
+ response.setStatus(HttpStatus.FORBIDDEN.value());
|
|
|
+ ServletUtil.returnJson(
|
|
|
+ new StatusResponse("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 StatusResponse("403", "第三方接入请求头['rootOrgId','timestamp']必须是整数"), response);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ request.setAttribute("$rootOrgId", Long.parseLong(rootOrgId));
|
|
|
+
|
|
|
+ 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 StatusResponse("403", e.getDesc()), response);
|
|
|
+ return false;
|
|
|
+ } catch (Exception e) {
|
|
|
+ response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
|
|
|
+ ServletUtil.returnJson(new StatusResponse("500", "获取第三方接入信息异常"), response);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ redisClient.set(key, thirdPartyAccessBean, 60000);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (null != thirdPartyAccessBean.getTimeRange()) {
|
|
|
+ long timestampLong = Long.parseLong(timestamp);
|
|
|
+ long currentTimeMillis = System.currentTimeMillis();
|
|
|
+ if (Math.abs(currentTimeMillis - timestampLong) > thirdPartyAccessBean.getTimeRange()) {
|
|
|
+ response.setStatus(HttpStatus.FORBIDDEN.value());
|
|
|
+ ServletUtil.returnJson(new StatusResponse("403", "timestamp超出时间差范围"), response);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ 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 StatusResponse("403", "access_token校验失败"), response);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|