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 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); } }