프로젝트 로그와 게이트웨이가 IP 화이트리스트를 처리할 때 일반적으로 사용자 IP를 얻고 방문자의 실제 IP는 일반적으로 HttpServletRequest 및 ServerHttpRequest에서 얻습니다.
1. HttpServletRequest에서 가져오기(로그 인쇄의 경우):
public static String getIpAddr(HttpServletRequest request){
String ip = null;
String ipAddresses = request.getHeader("X-Forwarded-For");
if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses))
{
ipAddresses = request.getHeader("Proxy-Client-IP");
}
if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses))
{
ipAddresses = request.getHeader("WL-Proxy-Client-IP");
}
if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses))
{
ipAddresses = request.getHeader("HTTP_CLIENT_IP");
}
if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses))
{
ipAddresses = request.getHeader("X-Real-IP");
}
if (ipAddresses != null && ipAddresses.length() != 0)
{
ip = ipAddresses.split(",")[0];
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses))
{
ip = request.getRemoteAddr();
}
return ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip;
}
2. ServerHttpRequest에서 얻은 (SpringCloud-Gateway 2세대 게이트웨이)
public static String getIpAddress(ServerHttpRequest request) {
HttpHeaders headers = request.getHeaders();
String ip = headers.getFirst("x-forwarded-for");
if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
if (ip.indexOf(",") != -1) {
ip = ip.split(",")[0];
}
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = headers.getFirst("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = headers.getFirst("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = headers.getFirst("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = headers.getFirst("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = headers.getFirst("X-Real-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddress().getAddress().getHostAddress();
}
return ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip;
}
IP를 얻은 후 화이트리스트를 필터링하는 방법
package com.maorong.gateway.config.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.List;
@Configuration
@RefreshScope
@ConfigurationProperties(prefix = "whiteip")
public class WhiteIpListProperties
{
private List<String> whites = new ArrayList<>();
public List<String> getWhites()
{
return whites;
}
public void setWhites(List<String> whites)
{
this.whites = whites;
}
}
Nacos 구성 정보:
게이트웨이 필터 추가 필터
@Component
public class AuthFilter implements GlobalFilter, Ordered
{
private static final Logger log = LoggerFactory.getLogger(AuthFilter.class);
private final static long EXPIRE_TIME = Constants.TOKEN_EXPIRE * 60;
@Autowired
private WhiteIpListProperties WhiteIp;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain)
{
String reqIp = IPUtils.getIpAddress(exchange.getRequest());
log.info("<<<<<<<请求的reqIp:"+reqIp);
if (!StringUtils.matches(reqIp, WhiteIp.getWhites()))
{
return setUnauthorizedResponse(exchange, "没有权限访问!");
}
}
IP 화이트리스트가 구성되었는지 확인
public class StringUtils extends org.apache.commons.lang3.StringUtils{
public static boolean matches(String str, List<String> strs)
{
if (isEmpty(str) || isEmpty(strs))
{
return false;
}
for (String testStr : strs)
{
if (matches(str, testStr))
{
return true;
}
}
return false;
}
public static boolean matches(String str, String... strs)
{
if (isEmpty(str) || isEmpty(strs))
{
return false;
}
for (String testStr : strs)
{
if (matches(str, testStr))
{
return true;
}
}
return false;
}
public static boolean matches(String str, String pattern)
{
if (isEmpty(pattern) || isEmpty(str))
{
return false;
}
pattern = pattern.replaceAll("\\s*", "");
int beginOffset = 0;
int formerStarOffset = -1;
int latterStarOffset = -1;
String remainingURI = str;
String prefixPattern = "";
String suffixPattern = "";
boolean result = false;
do
{
formerStarOffset = indexOf(pattern, START, beginOffset);
prefixPattern = substring(pattern, beginOffset, formerStarOffset > -1 ? formerStarOffset : pattern.length());
result = remainingURI.contains(prefixPattern);
if (formerStarOffset == -1)
{
return result;
}
if (!result)
return false;
if (!isEmpty(prefixPattern))
{
remainingURI = substringAfter(str, prefixPattern);
}
latterStarOffset = indexOf(pattern, START, formerStarOffset + 1);
suffixPattern = substring(pattern, formerStarOffset + 1, latterStarOffset > -1 ? latterStarOffset : pattern.length());
result = remainingURI.contains(suffixPattern);
if (!result)
return false;
if (!isEmpty(suffixPattern))
{
remainingURI = substringAfter(str, suffixPattern);
}
beginOffset = latterStarOffset + 1;
}
while (!isEmpty(suffixPattern) && !isEmpty(remainingURI));
return true;
}
@SuppressWarnings("unchecked")
public static <T> T cast(Object obj)
{
return (T) obj;
}
public static boolean isEmpty(String str)
{
return isNull(str) || NULLSTR.equals(str.trim());
}
}