初始项目
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
package com.cxytiandi.encrypt.springboot;
|
||||
|
||||
public class HttpMethodTypePrefixConstant {
|
||||
|
||||
public static final String GET = "get:";
|
||||
|
||||
public static final String POST = "post:";
|
||||
|
||||
public static final String DELETE = "delete:";
|
||||
|
||||
public static final String PUT = "put:";
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.cxytiandi.encrypt.springboot.annotation;
|
||||
|
||||
/**
|
||||
* 解密注解
|
||||
* <p>
|
||||
* <p>加了此注解的接口将进行数据解密操作<p>
|
||||
*
|
||||
* @author zscat
|
||||
* @about 2019-04-30
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface Decrypt {
|
||||
|
||||
String value() default "";
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.cxytiandi.encrypt.springboot.annotation;
|
||||
|
||||
import com.cxytiandi.encrypt.springboot.autoconfigure.EncryptAutoConfiguration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* 启用加密Starter
|
||||
* <p>
|
||||
* <p>在Spring Boot启动类上加上此注解<p>
|
||||
* <p>
|
||||
* <pre class="code">
|
||||
* @SpringBootApplication
|
||||
* @EnableEncrypt
|
||||
* public class App {
|
||||
* public static void main(String[] args) {
|
||||
* SpringApplication.run(App.class, args);
|
||||
* }
|
||||
* }
|
||||
* <pre>
|
||||
*
|
||||
* @author zscat
|
||||
*
|
||||
* @about 2019-04-30
|
||||
*/
|
||||
@Target({ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Inherited
|
||||
@Import({EncryptAutoConfiguration.class})
|
||||
public @interface EnableEncrypt {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.cxytiandi.encrypt.springboot.annotation;
|
||||
|
||||
/**
|
||||
* 加密注解
|
||||
* <p>
|
||||
* <p>加了此注解的接口将进行数据加密操作<p>
|
||||
*
|
||||
* @author zscat
|
||||
* @about 2019-04-30
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface Encrypt {
|
||||
|
||||
String value() default "";
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.cxytiandi.encrypt.springboot.annotation;
|
||||
|
||||
/**
|
||||
* 指定某个方法不需要加密
|
||||
*
|
||||
* @author zscat
|
||||
* @about 2019-04-30
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface NotNeedEncrypt {
|
||||
String value() default "";
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.cxytiandi.encrypt.springboot.autoconfigure;
|
||||
|
||||
import com.cxytiandi.encrypt.algorithm.EncryptAlgorithm;
|
||||
import com.cxytiandi.encrypt.core.EncryptionConfig;
|
||||
import com.cxytiandi.encrypt.core.EncryptionFilter;
|
||||
import com.cxytiandi.encrypt.springboot.init.ApiEncryptDataInit;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
|
||||
/**
|
||||
* 加解密自动配置
|
||||
*
|
||||
* @author zscat
|
||||
* @about 2019-04-30
|
||||
*/
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@EnableConfigurationProperties(EncryptionConfig.class)
|
||||
public class EncryptAutoConfiguration {
|
||||
|
||||
@Autowired
|
||||
private EncryptionConfig encryptionConfig;
|
||||
|
||||
@Autowired(required = false)
|
||||
private EncryptAlgorithm encryptAlgorithm;
|
||||
|
||||
/**
|
||||
* 不要用泛型注册Filter,泛型在Spring Boot 2.x版本中才有
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
@Bean
|
||||
public FilterRegistrationBean filterRegistration() {
|
||||
FilterRegistrationBean registration = new FilterRegistrationBean();
|
||||
if (encryptAlgorithm != null) {
|
||||
registration.setFilter(new EncryptionFilter(encryptionConfig, encryptAlgorithm));
|
||||
} else {
|
||||
registration.setFilter(new EncryptionFilter(encryptionConfig));
|
||||
}
|
||||
registration.addUrlPatterns(encryptionConfig.getUrlPatterns());
|
||||
registration.setName("EncryptionFilter");
|
||||
registration.setOrder(encryptionConfig.getOrder());
|
||||
return registration;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ApiEncryptDataInit apiEncryptDataInit() {
|
||||
return new ApiEncryptDataInit();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
package com.cxytiandi.encrypt.springboot.init;
|
||||
|
||||
import com.cxytiandi.encrypt.springboot.HttpMethodTypePrefixConstant;
|
||||
import com.cxytiandi.encrypt.springboot.annotation.Decrypt;
|
||||
import com.cxytiandi.encrypt.springboot.annotation.Encrypt;
|
||||
import com.cxytiandi.encrypt.springboot.annotation.NotNeedEncrypt;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ApiEncryptDataInit implements ApplicationContextAware {
|
||||
|
||||
/**
|
||||
* 需要对响应内容进行加密的接口URI<br>
|
||||
* 比如:/user/list<br>
|
||||
* 不支持@PathVariable格式的URI
|
||||
*/
|
||||
public static List<String> responseEncryptUriList = new ArrayList<String>();
|
||||
/**
|
||||
* 需要对请求内容进行解密的接口URI<br>
|
||||
* 比如:/user/list<br>
|
||||
* 不支持@PathVariable格式的URI
|
||||
*/
|
||||
public static List<String> requestDecyptUriList = new ArrayList<String>();
|
||||
/**
|
||||
* 需要对请求内容进行不需要解密的URI<br>
|
||||
* 比如:/user/list<br>
|
||||
* 不支持@PathVariable格式的URI
|
||||
*/
|
||||
public static List<String> requestNoNeedDecyptUriList = new ArrayList<String>();
|
||||
private Logger logger = LoggerFactory.getLogger(ApiEncryptDataInit.class);
|
||||
private String contextPath;
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext ctx) throws BeansException {
|
||||
this.contextPath = ctx.getEnvironment().getProperty("server.servlet.context-path");
|
||||
Map<String, Object> beanMap = ctx.getBeansWithAnnotation(RestController.class);
|
||||
initData(beanMap);
|
||||
beanMap = ctx.getBeansWithAnnotation(Controller.class);
|
||||
initData(beanMap);
|
||||
}
|
||||
|
||||
private void initData(Map<String, Object> beanMap) {
|
||||
if (beanMap != null) {
|
||||
for (Object bean : beanMap.values()) {
|
||||
Class<?> clz = bean.getClass();
|
||||
Method[] methods = clz.getMethods();
|
||||
for (Method method : methods) {
|
||||
if (method.isAnnotationPresent(Encrypt.class)) {
|
||||
// 注解中的URI优先级高
|
||||
String uri = method.getAnnotation(Encrypt.class).value();
|
||||
if (!StringUtils.hasText(uri)) {
|
||||
uri = getApiUri(clz, method);
|
||||
}
|
||||
logger.debug("Encrypt URI: {}", uri);
|
||||
responseEncryptUriList.add(uri);
|
||||
}
|
||||
if (method.isAnnotationPresent(Decrypt.class)) {
|
||||
String uri = method.getAnnotation(Decrypt.class).value();
|
||||
if (!StringUtils.hasText(uri)) {
|
||||
uri = getApiUri(clz, method);
|
||||
}
|
||||
logger.debug("Decrypt URI: {}", uri);
|
||||
requestDecyptUriList.add(uri);
|
||||
}
|
||||
if (method.isAnnotationPresent(NotNeedEncrypt.class)) {
|
||||
String uri = method.getAnnotation(NotNeedEncrypt.class).value();
|
||||
if (!StringUtils.hasText(uri)) {
|
||||
uri = getApiUri(clz, method);
|
||||
}
|
||||
logger.debug("NotNeedEncrypt URI: {}", uri);
|
||||
requestNoNeedDecyptUriList.add(uri);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getApiUri(Class<?> clz, Method method) {
|
||||
String methodType = "";
|
||||
StringBuilder uri = new StringBuilder();
|
||||
|
||||
if (clz.isAnnotationPresent(RequestMapping.class)) {
|
||||
uri.append(formatUri(clz.getAnnotation(RequestMapping.class).value()[0]));
|
||||
}
|
||||
|
||||
if (method.isAnnotationPresent(GetMapping.class)) {
|
||||
|
||||
methodType = HttpMethodTypePrefixConstant.GET;
|
||||
uri.append(formatUri(method.getAnnotation(GetMapping.class).value()[0]));
|
||||
|
||||
} else if (method.isAnnotationPresent(PostMapping.class)) {
|
||||
|
||||
methodType = HttpMethodTypePrefixConstant.POST;
|
||||
uri.append(formatUri(method.getAnnotation(PostMapping.class).value()[0]));
|
||||
|
||||
} else if (method.isAnnotationPresent(RequestMapping.class)) {
|
||||
|
||||
RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
|
||||
RequestMethod m = requestMapping.method()[0];
|
||||
methodType = m.name().toLowerCase() + ":";
|
||||
uri.append(formatUri(requestMapping.value()[0]));
|
||||
|
||||
} else if (method.isAnnotationPresent(PutMapping.class)) {
|
||||
|
||||
methodType = HttpMethodTypePrefixConstant.PUT;
|
||||
uri.append(formatUri(method.getAnnotation(PutMapping.class).value()[0]));
|
||||
|
||||
} else if (method.isAnnotationPresent(GetMapping.class)) {
|
||||
|
||||
methodType = HttpMethodTypePrefixConstant.DELETE;
|
||||
uri.append(formatUri(method.getAnnotation(GetMapping.class).value()[0]));
|
||||
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(this.contextPath)) {
|
||||
return methodType + this.contextPath + uri.toString();
|
||||
}
|
||||
return methodType + uri.toString();
|
||||
}
|
||||
|
||||
private String formatUri(String uri) {
|
||||
if (uri.startsWith("/")) {
|
||||
return uri;
|
||||
}
|
||||
return "/" + uri;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user