package com.vincent.rsf.openApi.security.filter;
|
|
import com.vincent.rsf.openApi.entity.constant.Constants;
|
import com.vincent.rsf.openApi.security.service.AppAuthService;
|
import com.vincent.rsf.openApi.security.utils.TokenUtils;
|
import lombok.extern.slf4j.Slf4j;
|
import org.apache.tika.utils.StringUtils;
|
import org.springframework.core.annotation.Order;
|
import org.springframework.stereotype.Component;
|
import org.springframework.web.filter.OncePerRequestFilter;
|
|
import javax.annotation.Resource;
|
import javax.servlet.FilterChain;
|
import javax.servlet.ServletException;
|
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletResponse;
|
import java.io.IOException;
|
import java.io.PrintWriter;
|
|
/**
|
* AppId和AppSecret认证过滤器
|
*
|
* 用于验证请求头中的AppId和AppSecret
|
*
|
* @author vincent
|
* @since 2026-01-05
|
*/
|
@Slf4j
|
@Component
|
@Order(1)
|
public class AppIdAuthenticationFilter extends OncePerRequestFilter {
|
|
@Resource
|
private AppAuthService appAuthService;
|
|
|
@Override
|
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
|
throws ServletException, IOException {
|
|
String requestURI = request.getRequestURI();
|
|
// 检查是否为认证请求(如获取token)
|
if (isAuthRequest(requestURI)) {
|
// 对于认证请求,允许通过
|
filterChain.doFilter(request, response);
|
return;
|
}
|
|
String authHeader = request.getHeader(Constants.HEADER_AUTHORIZATION);
|
if (authHeader != null) {
|
String token = TokenUtils.extractTokenFromHeader(authHeader);
|
if (token != null && TokenUtils.validateTokenTime(token)) {
|
// Token时间认证成功,认证AppId和AppSecret
|
String tokenAppId = TokenUtils.getAppIdFromToken(token);
|
String tokenAppSecret = TokenUtils.getSecretFromToken(token);
|
if (StringUtils.isBlank(tokenAppId) || StringUtils.isBlank(tokenAppSecret)
|
|| !appAuthService.validateApp(tokenAppId, tokenAppSecret)) {
|
log.warn("Token验证失败");
|
sendErrorResponse(response, Integer.parseInt(Constants.UNAUTHENTICATED_CODE), "认证失败,请提供有效的Token");
|
return;
|
} else {
|
request.setAttribute(Constants.REQUEST_ATTR_APP_ID, tokenAppId);
|
}
|
} else {
|
log.warn("Token验证失败或缺失");
|
sendErrorResponse(response, Integer.parseInt(Constants.UNAUTHENTICATED_CODE), "认证失败,请提供有效的Token");
|
return;
|
}
|
} else {
|
log.warn("缺少Token认证信息");
|
sendErrorResponse(response, Integer.parseInt(Constants.UNAUTHENTICATED_CODE), "认证失败,请提供有效的Token");
|
return;
|
}
|
|
filterChain.doFilter(request, response);
|
}
|
|
/**
|
* 发送错误响应
|
*
|
* @param response HTTP响应
|
* @param code 错误码
|
* @param message 错误消息
|
* @throws IOException
|
*/
|
private void sendErrorResponse(HttpServletResponse response, int code, String message) throws IOException {
|
response.setStatus(code);
|
response.setContentType("application/json;charset=UTF-8");
|
PrintWriter writer = response.getWriter();
|
writer.write("{\"code\": \"" + code + "\", \"msg\": \"" + message + "\", \"data\": null}");
|
writer.flush();
|
}
|
|
/**
|
* 检查是否为认证请求(不需要认证的请求)
|
*
|
* @param requestURI 请求URI
|
* @return 是否为认证请求
|
*/
|
private boolean isAuthRequest(String requestURI) {
|
return requestURI.contains("/getToken");
|
// || requestURI.contains("/auth/validate") ||
|
// requestURI.contains("/auth/login");
|
}
|
|
@Override
|
protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
|
String requestURI = request.getRequestURI();
|
|
// 不过滤认证相关请求和公开接口
|
return requestURI.contains("/auth/") ||
|
requestURI.contains("/public/") ||
|
requestURI.contains("/doc.html") ||
|
requestURI.contains("/swagger") ||
|
requestURI.contains("/webjars") ||
|
requestURI.contains("/v2/api-docs") ||
|
requestURI.contains("/v3/api-docs");
|
}
|
|
}
|