package com.ruoyi.web.controller.hanler;
|
|
import com.ruoyi.common.annotation.IpWhitelist;
|
import com.ruoyi.system.domain.SysConfig;
|
import com.ruoyi.system.mapper.SysConfigMapper;
|
import org.apache.commons.net.util.SubnetUtils;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.http.HttpStatus;
|
import org.springframework.stereotype.Component;
|
import org.springframework.web.method.HandlerMethod;
|
import org.springframework.web.servlet.HandlerInterceptor;
|
|
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletResponse;
|
import java.util.Arrays;
|
import java.util.List;
|
import java.util.regex.Pattern;
|
|
@Component
|
public class IpWhitelistInterceptor implements HandlerInterceptor {
|
@Autowired
|
private SysConfigMapper sysConfigMapper;
|
|
@Override
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
System.out.println("处理器类: " + handler.getClass().getName());
|
if (handler instanceof HandlerMethod) {
|
HandlerMethod handlerMethod = (HandlerMethod) handler;
|
if (handlerMethod.hasMethodAnnotation(IpWhitelist.class)) {
|
//获取请求的IP,判断是不是在白名单中
|
String clientIp = getClientIp(request);
|
if (!isIpInWhitelist(clientIp)) {
|
response.setStatus(HttpStatus.FORBIDDEN.value());
|
response.getWriter().write("Access denied: IP address not whitelisted");
|
return false;
|
}
|
}
|
}
|
return true;
|
}
|
|
private String getClientIp(HttpServletRequest request) {
|
String ip = request.getHeader("X-Forwarded-For");
|
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
|
ip = request.getHeader("Proxy-Client-IP");
|
}
|
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
|
ip = request.getHeader("WL-Proxy-Client-IP");
|
}
|
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
|
ip = request.getRemoteAddr();
|
}
|
return ip;
|
}
|
|
private boolean isIpInWhitelist(String ip) {
|
try {
|
SysConfig config = new SysConfig();
|
config.setConfigKey("sys.ip.whitelist");
|
SysConfig sysConfig = sysConfigMapper.selectConfig(config);
|
List<String> whitelistIps = Arrays.asList(sysConfig.getConfigValue().split(","));
|
for (String whitelist : whitelistIps) {
|
if (isInRange(ip, whitelist)) {
|
return true;
|
}
|
}
|
} catch (Exception e) {
|
return false;
|
}
|
return false;
|
}
|
|
/**
|
* 智能验证IP是否在指定的模式内
|
* 支持:CIDR格式、通配符格式、单个IP
|
*/
|
public boolean isInRange(String ip, String pattern) {
|
if (pattern == null || ip == null) {
|
return false;
|
}
|
|
// 1. 如果是CIDR格式(包含/)
|
if (pattern.contains("/")) {
|
try {
|
SubnetUtils utils = new SubnetUtils(pattern);
|
return utils.getInfo().isInRange(ip);
|
} catch (IllegalArgumentException e) {
|
return false;
|
}
|
}
|
|
// 2. 如果是通配符格式(包含*)
|
if (pattern.contains("*")) {
|
return matchesWildcardPattern(ip, pattern);
|
}
|
|
// 3. 如果是单个IP地址
|
if (isValidIp(pattern)) {
|
return ip.equals(pattern);
|
}
|
|
return false;
|
}
|
|
/**
|
* 通配符模式匹配
|
*/
|
private boolean matchesWildcardPattern(String ip, String wildcardPattern) {
|
// 将通配符转换为正则表达式
|
String regex = wildcardPattern.replace(".", "\\.").replace("*", "\\d+");
|
|
return Pattern.matches(regex, ip);
|
}
|
|
/**
|
* 验证是否为合法IP地址
|
*/
|
private boolean isValidIp(String ip) {
|
return Pattern.matches("^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$", ip);
|
}
|
}
|