環境変数「ALLOW_IP_ADDRESS_RANGES」に許可するアドレス範囲を定義しておく
「1.1.1.1-1.1.1.1, 1.1.1.10-1.1.1.11」形式
チェックを行わない場合は設定しないこと
接続元IPはrequest.getRemoteAddr()で取得しているが、必要に応じてX-Forwarded-Forヘッダから取得する
Herokuではrequest.getRemoteAddr()で取得可能 - https://help.heroku.com/FIX647OC/why-can-t-i-access-the-x-forwarded-for-header-in-my-java-spring-app
private static final String ALLOW_IP_ADDRESS_RANGES = System.getenv("ALLOW_IP_ADDRESS_RANGES");
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class IpAddressFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
if (ALLOW_IP_ADDRESS_RANGES != null && !ALLOW_IP_ADDRESS_RANGES.isEmpty()) {
String remoteIpAddress = formatIpAddress(getRemoteIpAddress((HttpServletRequest) request));
String[] allowIpAddressRanges = ALLOW_IP_ADDRESS_RANGES.split(",");
boolean allowed = false;
for (String allowIpAddressRange : allowIpAddressRanges) {
String[] allowIpAddressRangeSplit = allowIpAddressRange.trim().split("-");
String allowIpAddressLow = formatIpAddress(allowIpAddressRangeSplit[0]);
String allowIpAddressHigh = formatIpAddress(allowIpAddressRangeSplit[1]);
if (remoteIpAddress.compareTo(allowIpAddressLow) < 0 || 0 < remoteIpAddress.compareTo(allowIpAddressHigh)) {
log.trace("remote ip address {} is not in range({}-{})", remoteIpAddress, allowIpAddressLow, allowIpAddressHigh);
} else {
log.trace("remote ip address {} is in range({}-{})", remoteIpAddress, allowIpAddressLow, allowIpAddressHigh);
allowed = true;
break;
}
}
if (!allowed) {
log.info("remote ip address {} is not included in environment variable {}", remoteIpAddress, ALLOW_IP_ADDRESS_RANGES);
((HttpServletResponse) response).sendError(HttpServletResponse.SC_FORBIDDEN);
return;
}
} else {
log.trace("environment variable {} not set", ALLOW_IP_ADDRESS_RANGES);
}
chain.doFilter(request, response);
}
private String getRemoteIpAddress(HttpServletRequest request) {
String remoteIpAddress;
String xForwardedFor = request.getHeader("X-Forwarded-For");
if (xForwardedFor != null && !xForwardedFor.isEmpty()) {
remoteIpAddress = xForwardedFor.split(",")[0].trim();
} else {
remoteIpAddress = request.getRemoteAddr();
}
return remoteIpAddress;
}
private String formatIpAddress(String ipAddress) {
String[] nums = ipAddress.split("\\.");
StringBuilder stringBuilder = new StringBuilder();
for (String num : nums) {
if (stringBuilder.length() > 0) {
stringBuilder.append('.');
}
stringBuilder.append(String.format("%03d", Integer.parseInt(num)));
}
return stringBuilder.toString();
}
}