|
@@ -0,0 +1,107 @@
|
|
|
|
|
+package com.usoftchina.smartschool.wechat.auth.interceptor;
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+import com.usoftchina.smartschool.wechat.auth.annotation.IgnoreOpenApiAuth;
|
|
|
|
|
+import com.usoftchina.smartschool.wechat.auth.configuration.OpenApiConfig;
|
|
|
|
|
+import org.slf4j.Logger;
|
|
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
+import org.springframework.http.HttpStatus;
|
|
|
|
|
+import org.springframework.scheduling.annotation.Scheduled;
|
|
|
|
|
+import org.springframework.web.method.HandlerMethod;
|
|
|
|
|
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
|
|
|
|
|
+
|
|
|
|
|
+import javax.servlet.http.HttpServletRequest;
|
|
|
|
|
+import javax.servlet.http.HttpServletResponse;
|
|
|
|
|
+import java.util.Map;
|
|
|
|
|
+import java.util.concurrent.ConcurrentHashMap;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * @author: guq
|
|
|
|
|
+ * @create: 2019-01-10 16:05
|
|
|
|
|
+ **/
|
|
|
|
|
+public class OpenApiAuthInterceptor extends HandlerInterceptorAdapter{
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private OpenApiConfig openApiConfig;
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private CompanyApi companyApi;
|
|
|
|
|
+
|
|
|
|
|
+ // 已使用签名
|
|
|
|
|
+ private Map<String, Long> signatureCache = new ConcurrentHashMap<>();
|
|
|
|
|
+
|
|
|
|
|
+ private static Logger logger = LoggerFactory.getLogger(OpenApiAuthInterceptor.class);
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
|
|
|
|
+ if (handler instanceof HandlerMethod) {
|
|
|
|
|
+ HandlerMethod handlerMethod = (HandlerMethod) handler;
|
|
|
|
|
+ // 配置该注解,说明不进行用户拦截
|
|
|
|
|
+ IgnoreOpenApiAuth annotation = handlerMethod.getBeanType().getAnnotation(IgnoreOpenApiAuth.class);
|
|
|
|
|
+ if (annotation == null) {
|
|
|
|
|
+ annotation = handlerMethod.getMethodAnnotation(IgnoreOpenApiAuth.class);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (annotation != null) {
|
|
|
|
|
+ return super.preHandle(request, response, handler);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ String sign = request.getParameter(openApiConfig.getSignatureParam());
|
|
|
|
|
+ String companyuu = request.getParameter(openApiConfig.getSchool());
|
|
|
|
|
+ if (!StringUtils.isEmpty(sign) && !StringUtils.isEmpty(companyuu)) {
|
|
|
|
|
+ String urlMessage = request.getRequestURI() + "?"
|
|
|
|
|
+ + request.getQueryString().substring(0, request.getQueryString().indexOf(openApiConfig.getSignatureParam()) - 1);
|
|
|
|
|
+
|
|
|
|
|
+ logger.info("urlMessage:{}", urlMessage);
|
|
|
|
|
+ String servletPath = request.getServletPath();
|
|
|
|
|
+ logger.info("servletPath:{}", servletPath);
|
|
|
|
|
+
|
|
|
|
|
+ boolean check = false;
|
|
|
|
|
+ //获取密钥
|
|
|
|
|
+ Result<CompanyDTO> companyResult = companyApi.getCompanyByUu(Long.valueOf(companyuu));
|
|
|
|
|
+ if (companyResult.isSuccess()) {
|
|
|
|
|
+ String localSign = null;
|
|
|
|
|
+
|
|
|
|
|
+ TransfersContextHodler.setB2bCompanyId(companyResult.getData().getId());
|
|
|
|
|
+
|
|
|
|
|
+ localSign = companyResult.getData().getAccessKey() == null ? HmacUtils.encode(urlMessage) :
|
|
|
|
|
+ HmacUtils.encode(urlMessage, companyResult.getData().getAccessKey());
|
|
|
|
|
+
|
|
|
|
|
+ if (servletPath.indexOf("b2b") > -1) {
|
|
|
|
|
+ logger.info("自己生产的sign:{}-----传入的sign:{}", localSign, sign);
|
|
|
|
|
+ check = sign.equals(localSign);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (check) {
|
|
|
|
|
+ String timestamp = request.getParameter(openApiConfig.getTimestampParam());
|
|
|
|
|
+ long now = System.currentTimeMillis();
|
|
|
|
|
+ if (!StringUtils.isEmpty(timestamp) && Math.abs(now - Long.parseLong(timestamp)) <= openApiConfig.getTimeout()
|
|
|
|
|
+ && !signatureCache.containsKey(sign)) {
|
|
|
|
|
+ // 加入历史记录
|
|
|
|
|
+ signatureCache.put(sign, now);
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ response.setStatus(HttpStatus.FORBIDDEN.value());
|
|
|
|
|
+ return false;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ }
|
|
|
|
|
+ return super.preHandle(request, response, handler);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 清除签名池历史记录
|
|
|
|
|
+ */
|
|
|
|
|
+ @Scheduled(cron = "0 0/3 * * * ?")
|
|
|
|
|
+ public void clearCache() {
|
|
|
|
|
+ long now = System.currentTimeMillis();
|
|
|
|
|
+ for (String key : signatureCache.keySet()) {
|
|
|
|
|
+ long time = signatureCache.get(key);
|
|
|
|
|
+ if (now - time > openApiConfig.getTimeout()) {
|
|
|
|
|
+ signatureCache.remove(key);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|