package com.tcm.training.admin.config;
|
|
import com.tcm.training.admin.app.auth.support.StpAppUserUtil;
|
import cn.dev33.satoken.interceptor.SaInterceptor;
|
import cn.dev33.satoken.context.SaHolder;
|
import cn.dev33.satoken.stp.StpUtil;
|
import com.tcm.training.admin.common.xss.XssParamInterceptor;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.context.annotation.Configuration;
|
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.io.File;
|
|
@Configuration
|
public class SaTokenWebConfig implements WebMvcConfigurer {
|
|
private final XssParamInterceptor xssParamInterceptor;
|
|
@Value("${app.upload.dir:uploads}")
|
private String uploadDir;
|
|
@Value("${app.upload.path-prefix:/uploads}")
|
private String pathPrefix;
|
|
public SaTokenWebConfig(XssParamInterceptor xssParamInterceptor) {
|
this.xssParamInterceptor = xssParamInterceptor;
|
}
|
|
/**
|
* 注册 Sa-Token 与 XSS 拦截器。
|
*/
|
@Override
|
public void addInterceptors(InterceptorRegistry registry) {
|
registry.addInterceptor(new SaInterceptor(handle -> handleAuth()))
|
.addPathPatterns("/api/**", "/api/v1/**")
|
.excludePathPatterns(
|
pathPrefix + "/**"
|
);
|
|
registry.addInterceptor(xssParamInterceptor)
|
.addPathPatterns("/api/**", "/api/v1/**");
|
}
|
|
/**
|
* 按请求路径切换管理员鉴权与 APP 鉴权。
|
*/
|
private void handleAuth() {
|
if ("OPTIONS".equalsIgnoreCase(SaHolder.getRequest().getMethod())) {
|
return;
|
}
|
String requestPath = SaHolder.getRequest().getRequestPath();
|
if (isAppApi(requestPath)) {
|
if (isPublicAppApi(requestPath)) {
|
return;
|
}
|
StpAppUserUtil.checkLogin();
|
return;
|
}
|
if (isPublicAdminApi(requestPath)) {
|
return;
|
}
|
StpUtil.checkLogin();
|
}
|
|
/**
|
* 判断是否属于 APP 路由空间。
|
*/
|
private boolean isAppApi(String requestPath) {
|
return requestPath.startsWith("/api/app/") || requestPath.startsWith("/api/v1/app/");
|
}
|
|
/**
|
* 判断当前 APP 路由是否允许匿名访问。
|
*/
|
private boolean isPublicAppApi(String requestPath) {
|
return requestPath.startsWith("/api/app/auth/")
|
|| requestPath.startsWith("/api/v1/app/auth/")
|
|| "/api/app/version/check".equals(requestPath)
|
|| "/api/v1/app/version/check".equals(requestPath);
|
}
|
|
/**
|
* 判断当前后台路由是否允许匿名访问。
|
*/
|
private boolean isPublicAdminApi(String requestPath) {
|
return "/api/auth/login".equals(requestPath)
|
|| "/api/auth/captcha".equals(requestPath);
|
}
|
|
/**
|
* 将本地上传目录映射为静态资源,可通过 /uploads/** 访问。
|
*/
|
@Override
|
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
// 转为绝对路径,确保 file: 协议正确。
|
String absPath = new File(uploadDir).getAbsolutePath();
|
registry.addResourceHandler(pathPrefix + "/**")
|
.addResourceLocations("file:" + absPath + "/");
|
}
|
}
|