Nginx配置文件
127.0.0.1_8965.conf
server {
listen 8965;
server_name 127.0.0.1;
# 文件请求
location /file/ {
root D:/home/pmps/;
#autoindex on;
# 设置鉴权的请求
auth_request /authFileValid;
# 从URL查询参数中获取 token,并赋值给token变量
set $token $arg_Token;
# 从请求头Token,并赋值给token变量
#set $token $http_Token;
# 直接返回错误信息
error_page 401 = /auth-required;
}
location = /authFileValid {
internal; # 只允许内部访问
proxy_pass http://127.0.0.1:8960/system/file/auth;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
# 设置Token 的值为变量token
proxy_set_header Token "$token";
}
location = /auth-required {
return 401; # 返回 401 状态码
}
# 其他接口请求
location / {
client_max_body_size 100m;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8960/;
}
}
Java鉴权代码示例
我这里用的是SaToken,token请求头名是:Token
java
import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.context.SaHolder;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import java.net.URI;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.regex.Pattern;
/**
* 系统文件相关
*/
@Tag(name = "系统文件管理", description = "系统文件相关接口")
@RestController
@RequestMapping("/system/file")
public class SysFileController extends BaseController {
@RequestMapping("/auth")
@ResponseBody
@SaIgnore
public void authFileValid(HttpServletRequest request, HttpServletResponse response) {
String token = request.getHeader("Token");
if (ObjectUtil.isEmpty(token)) {
response.setStatus(HttpStatus.UNAUTHORIZED.value());
return;
}
LoginUserBo loginUserByToken = LoginHelper.getLoginUserByToken(token);
if (ObjectUtil.isNull(loginUserByToken)) {
response.setStatus(HttpStatus.UNAUTHORIZED.value());
return;
}
String originalURI = request.getHeader("X-Original-URI");
boolean b = validateURIWithWhitelist(originalURI);
if (!b) {
response.setStatus(HttpStatus.UNAUTHORIZED.value());
} else {
response.setStatus(HttpStatus.OK.value());
}
}
//这里越权检查,你可以自行更换其他更好的写法
public boolean validateURIWithWhitelist(String originalURI) {
if (originalURI == null) {
return false;
}
try {
URI uri = new URI(originalURI);
String path = uri.getPath();
if (path == null) {
return false;
}
// 定义允许的路径模式 - 不限制文件后缀
// 格式: /file/2025/10/96da59e0edc2a7fa2ab7959b286235e.xxx
Pattern allowedPattern = Pattern.compile("^/file/\\d{4}/\\d{2}/[a-zA-Z0-9][a-zA-Z0-9.-]*\\.[a-zA-Z0-9]+$");
// 验证路径格式
if (!allowedPattern.matcher(path).matches()) {
return false;
}
return !path.contains("..") && path.split("/").length >= 5;
} catch (Exception e) {
return false;
}
}
}