177 lines
7.7 KiB
Java
177 lines
7.7 KiB
Java
package com.changhu.config;
|
|
|
|
import cn.dev33.satoken.interceptor.SaInterceptor;
|
|
import cn.dev33.satoken.stp.StpUtil;
|
|
import cn.hutool.core.collection.CollUtil;
|
|
import cn.hutool.core.util.ClassUtil;
|
|
import com.changhu.common.annotation.IsWhiteList;
|
|
import com.changhu.common.annotation.JsonBody;
|
|
import com.changhu.filter.BodyWrapperFilter;
|
|
import com.changhu.interceptor.JsonBodyInterceptor;
|
|
import com.changhu.interceptor.OpenApiAuthInterceptor;
|
|
import com.changhu.interceptor.UserTypeInterceptor;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.jetbrains.annotations.NotNull;
|
|
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
|
import org.springframework.context.annotation.Bean;
|
|
import org.springframework.context.annotation.Configuration;
|
|
import org.springframework.core.annotation.AnnotatedElementUtils;
|
|
import org.springframework.stereotype.Controller;
|
|
import org.springframework.web.bind.annotation.RequestMapping;
|
|
import org.springframework.web.bind.annotation.RestController;
|
|
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
|
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
|
|
|
import java.lang.annotation.Annotation;
|
|
import java.lang.reflect.Method;
|
|
import java.util.*;
|
|
import java.util.stream.Collectors;
|
|
|
|
/**
|
|
* author: luozhun
|
|
* desc: WebConfig
|
|
* createTime: 2023/8/18 10:56
|
|
*/
|
|
@Slf4j
|
|
@Configuration
|
|
public class WebConfig implements WebMvcConfigurer {
|
|
|
|
private final List<String> whiteList = new ArrayList<>();
|
|
|
|
/**
|
|
* 扫描所有Controller
|
|
*/
|
|
private static Set<Class<?>> scanRestController() {
|
|
//需要过滤出JsonBody
|
|
Set<Class<?>> classes = ClassUtil.scanPackage("com.changhu", clazz -> !JsonBody.class.equals(clazz));
|
|
return classes.stream().filter(aClass -> {
|
|
//判断类上是否有Controller注解
|
|
if (aClass.isAnnotationPresent(Controller.class) || aClass.isAnnotationPresent(RestController.class)) {
|
|
return true;
|
|
}
|
|
Annotation[] annotations = aClass.getAnnotations();
|
|
for (Annotation annotation : annotations) {
|
|
if (annotation.annotationType().isAnnotationPresent(Controller.class) || annotation.annotationType().isAnnotationPresent(RestController.class)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}).collect(Collectors.toSet());
|
|
}
|
|
|
|
public WebConfig() {
|
|
Set<String> w = new HashSet<>();
|
|
for (Class<?> clazz : scanRestController()) {
|
|
//类上的注解
|
|
RequestMapping classRequestMapping = AnnotatedElementUtils.findMergedAnnotation(clazz, RequestMapping.class);
|
|
IsWhiteList clazzIsWhiteList = clazz.getAnnotation(IsWhiteList.class);
|
|
if (classRequestMapping != null && clazzIsWhiteList != null) {
|
|
//直接放行当前控制器的所有方法
|
|
w.addAll(Arrays.stream(classRequestMapping.value()).map(path -> {
|
|
if (!path.startsWith("/")) {
|
|
path = "/" + path;
|
|
}
|
|
if (!path.endsWith("/")) {
|
|
path = path + "/";
|
|
}
|
|
return path + "**";
|
|
}).toList());
|
|
continue;
|
|
}
|
|
//看方法上是否有白名单注解
|
|
Method[] methods = clazz.getDeclaredMethods();
|
|
for (Method method : methods) {
|
|
IsWhiteList methodIsWhiteList = method.getAnnotation(IsWhiteList.class);
|
|
RequestMapping methodRequestMapping = AnnotatedElementUtils.findMergedAnnotation(method, RequestMapping.class);
|
|
if (methodRequestMapping != null && methodIsWhiteList != null) {
|
|
List<List<String>> list1 = Arrays.stream(methodRequestMapping.value()).map(path -> {
|
|
if (!path.startsWith("/")) {
|
|
path = "/" + path;
|
|
}
|
|
if (path.endsWith("/")) {
|
|
path = path.substring(0, path.length() - 1);
|
|
}
|
|
List<String> list = new ArrayList<>();
|
|
if (classRequestMapping != null && CollUtil.isNotEmpty(Arrays.asList(classRequestMapping.value()))) {
|
|
for (String p : classRequestMapping.value()) {
|
|
if (!p.startsWith("/")) {
|
|
p = "/" + p;
|
|
}
|
|
if (p.endsWith("/")) {
|
|
p = p.substring(0, p.length() - 1);
|
|
}
|
|
list.add(p + path);
|
|
}
|
|
} else {
|
|
list.add(path);
|
|
}
|
|
return list;
|
|
}).toList();
|
|
w.addAll(list1.stream().flatMap(List::stream).toList());
|
|
}
|
|
}
|
|
}
|
|
log.info("加载路由白名单:{}", w);
|
|
whiteList.addAll(w);
|
|
|
|
//网站图标
|
|
whiteList.add("/favicon.ico");
|
|
//druid console
|
|
whiteList.add("/druid/**");
|
|
//knife4j
|
|
whiteList.add("/doc.html/**");
|
|
whiteList.add("/static/**");
|
|
whiteList.add("/swagger-resources");
|
|
whiteList.add("/**webjars/**");
|
|
whiteList.add("/v3/**");
|
|
}
|
|
|
|
@Override
|
|
public void addInterceptors(@NotNull InterceptorRegistry registry) {
|
|
// 注册 Sa-Token 拦截器,校验规则为 StpUtil.checkLogin() 登录校验。
|
|
registry.addInterceptor(new SaInterceptor(handle -> StpUtil.checkLogin()))
|
|
.addPathPatterns("/**")
|
|
.excludePathPatterns(whiteList);
|
|
// 注册jsonBody拦截器 用于标识是否需要JsonResult返回
|
|
registry.addInterceptor(new JsonBodyInterceptor());
|
|
// 注册用户类型拦截器 用于校验当前用户是否匹配操作客户端
|
|
registry.addInterceptor(new UserTypeInterceptor());
|
|
// 注册开放接口认证拦截器 用于校验第三方是否授权
|
|
registry.addInterceptor(new OpenApiAuthInterceptor())
|
|
.addPathPatterns("/open/**");
|
|
}
|
|
|
|
@Bean
|
|
public FilterRegistrationBean<BodyWrapperFilter> loggingFilter() {
|
|
FilterRegistrationBean<BodyWrapperFilter> registrationBean = new FilterRegistrationBean<>();
|
|
registrationBean.setFilter(new BodyWrapperFilter());
|
|
registrationBean.addUrlPatterns("/open/*"); // 指定过滤的URL模式
|
|
registrationBean.setOrder(1000);
|
|
return registrationBean;
|
|
}
|
|
|
|
@Override
|
|
public void addCorsMappings(CorsRegistry registry) {
|
|
registry.addMapping("/**")
|
|
.allowedOriginPatterns("*")
|
|
.allowedMethods("GET", "POST", "OPTION", "PUT", "DELETE")
|
|
.allowedHeaders("Content-Type", "X-Requested-With", "accept", "Origin", "Access-Control-Request-Method",
|
|
"Access-Control-Request-Headers", "Authorization", "Token", "*")
|
|
.allowCredentials(true)
|
|
.maxAge(3600);
|
|
}
|
|
|
|
@Override
|
|
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
|
registry.addResourceHandler("doc.html")
|
|
.addResourceLocations("classpath:/META-INF/resources/");
|
|
registry.addResourceHandler("swagger-ui.html")
|
|
.addResourceLocations("classpath:/META-INF/resources/");
|
|
registry.addResourceHandler("/webjars/**")
|
|
.addResourceLocations("classpath:/META-INF/resources/webjars/");
|
|
}
|
|
|
|
}
|