Browse Source

openapi拦截器

guq 7 years ago
parent
commit
88b1e00247

+ 1 - 0
applications/transfers/pom.xml

@@ -17,6 +17,7 @@
         <module>transfers-server</module>
         <module>mall-api</module>
         <module>transfers-dto</module>
+        <module>transfers-auth</module>
     </modules>
 
 </project>

+ 39 - 0
applications/transfers/transfers-auth/pom.xml

@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>transfers</artifactId>
+        <groupId>com.usoftchina.saas</groupId>
+        <version>1.0.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>transfers-auth</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-netflix-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-webmvc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.usoftchina.saas</groupId>
+            <artifactId>auth-common</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>io.github.openfeign</groupId>
+            <artifactId>feign-core</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

+ 15 - 0
applications/transfers/transfers-auth/src/main/java/com/usoftchina/saas/transfers/auth/annotation/IgnoreOpenApiAuth.java

@@ -0,0 +1,15 @@
+package com.usoftchina.saas.transfers.auth.annotation;
+
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 对外接口忽略鉴权
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(value={ElementType.METHOD,ElementType.TYPE})
+public @interface IgnoreOpenApiAuth {
+}

+ 39 - 0
applications/transfers/transfers-auth/src/main/java/com/usoftchina/saas/transfers/auth/configuration/OpenApiConfig.java

@@ -0,0 +1,39 @@
+package com.usoftchina.saas.transfers.auth.configuration;
+import org.springframework.beans.factory.annotation.Value;
+/**
+ * @author: guq
+ * @create: 2019-01-10 15:58
+ **/
+public class OpenApiConfig {
+
+    @Value("${openapi.signatureParam:_signature}")
+    private String signatureParam;
+    @Value("${openapi.timestampParam:_timestamp}")
+    private String timestampParam;
+    @Value("${openapi.timeout:60000}")
+    private int timeout;
+
+    public String getSignatureParam() {
+        return signatureParam;
+    }
+
+    public void setSignatureParam(String signatureParam) {
+        this.signatureParam = signatureParam;
+    }
+
+    public String getTimestampParam() {
+        return timestampParam;
+    }
+
+    public void setTimestampParam(String timestampParam) {
+        this.timestampParam = timestampParam;
+    }
+
+    public int getTimeout() {
+        return timeout;
+    }
+
+    public void setTimeout(int timeout) {
+        this.timeout = timeout;
+    }
+}

+ 29 - 0
applications/transfers/transfers-auth/src/main/java/com/usoftchina/saas/transfers/auth/configuration/OpenApiConfiguration.java

@@ -0,0 +1,29 @@
+package com.usoftchina.saas.transfers.auth.configuration;
+
+import com.usoftchina.saas.transfers.auth.interceptor.OpenApiAuthInterceptor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * @author: guq
+ * @create: 2019-01-10 16:04
+ **/
+@Configuration
+public class OpenApiConfiguration implements WebMvcConfigurer {
+    @Bean
+    public OpenApiConfig openApiConfig() {
+        return new OpenApiConfig();
+    }
+
+    @Bean
+    public OpenApiAuthInterceptor openApiAuthInterceptor() {
+        return new OpenApiAuthInterceptor();
+    }
+
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        registry.addInterceptor(openApiAuthInterceptor());
+    }
+}

+ 90 - 0
applications/transfers/transfers-auth/src/main/java/com/usoftchina/saas/transfers/auth/interceptor/OpenApiAuthInterceptor.java

@@ -0,0 +1,90 @@
+package com.usoftchina.saas.transfers.auth.interceptor;
+
+import com.usoftchina.saas.transfers.auth.annotation.IgnoreOpenApiAuth;
+import com.usoftchina.saas.transfers.auth.configuration.OpenApiConfig;
+import com.usoftchina.saas.utils.StringUtils;
+import com.usoftchina.saas.utils.http.HmacUtils;
+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;
+
+    // 已使用签名
+    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());
+            if (!StringUtils.isEmpty(sign)) {
+                String urlMessage = request.getRequestURL() + "?"
+                        + 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;
+
+                if (servletPath.indexOf("openapi") > -1) {
+                    check = sign.equals(HmacUtils.encode(urlMessage));
+                }
+                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);
+            }
+        }
+    }
+}

+ 4 - 0
applications/transfers/transfers-server/pom.xml

@@ -65,6 +65,10 @@
             <groupId>org.mybatis.spring.boot</groupId>
             <artifactId>mybatis-spring-boot-starter</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.usoftchina.saas</groupId>
+            <artifactId>transfers-auth</artifactId>
+        </dependency>
     </dependencies>
 
     <build>

+ 2 - 0
applications/transfers/transfers-server/src/main/java/com/usoftchina/saas/transfers/TransfersApplication.java

@@ -1,5 +1,6 @@
 package com.usoftchina.saas.transfers;
 
+import com.usoftchina.saas.transfers.auth.EnableOpenApiAuthClient;
 import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -10,6 +11,7 @@ import org.springframework.cloud.openfeign.EnableFeignClients;
 @EnableEurekaClient
 @EnableFeignClients("com.usoftchina.saas")
 @MapperScan("com.usoftchina.saas.transfers.mapper")
+@EnableOpenApiAuthClient
 public class TransfersApplication {
     public static void main(String[] args) {
         SpringApplication.run(TransfersApplication.class, args);

+ 2 - 0
applications/transfers/transfers-server/src/main/java/com/usoftchina/saas/transfers/controller/TransfersController.java

@@ -1,6 +1,7 @@
 package com.usoftchina.saas.transfers.controller;
 
 import com.usoftchina.saas.base.Result;
+import com.usoftchina.saas.transfers.auth.annotation.IgnoreOpenApiAuth;
 import com.usoftchina.saas.transfers.service.SendService;
 import com.usoftchina.saas.utils.StringUtils;
 import com.usoftchina.saas.transfers.dto.MessageInfo;
@@ -16,6 +17,7 @@ import org.springframework.web.bind.annotation.RestController;
  **/
 @RestController
 @RequestMapping("/send")
+@IgnoreOpenApiAuth
 public class TransfersController {
 
     @Autowired

+ 5 - 0
pom.xml

@@ -342,6 +342,11 @@
                 <artifactId>datacenter-client</artifactId>
                 <version>${project.release.version}</version>
             </dependency>
+            <dependency>
+                <groupId>com.usoftchina.saas</groupId>
+                <artifactId>transfers-auth</artifactId>
+                <version>${project.release.version}</version>
+            </dependency>
             <!-- file upload -->
             <dependency>
                 <groupId>io.github.openfeign.form</groupId>