增加香港澳门新加坡IP屏蔽

This commit is contained in:
hy001 2026-05-09 13:45:41 +08:00
parent c82e4c91f7
commit 8d9b3b05d3
5 changed files with 119 additions and 5 deletions

View File

@ -38,6 +38,12 @@ public class LoginAccessValidationService {
private static final List<String> ALLOWED_CHINA_REGIONS = List.of(
"香港", "澳门", "澳門", "台湾", "台灣", "Hong Kong", "Macau", "Macao", "Taiwan"
);
private static final List<String> BLOCKED_COUNTRY_CODES = List.of(
"HK", "MO", "SG"
);
private static final List<String> BLOCKED_COUNTRY_NAMES = List.of(
"香港", "澳门", "澳門", "Hong Kong", "Macau", "Macao", "新加坡", "Singapore"
);
private static final List<IpGeoProvider> IP_GEO_PROVIDERS = List.of(
new IpGeoProvider("ip.sb", "https://api.ip.sb/geoip/%s"),
new IpGeoProvider("freeipapi", "https://freeipapi.com/api/json/%s"),
@ -144,7 +150,7 @@ public class LoginAccessValidationService {
}
private boolean isIpValidationFailed(String ip) {
return isMainlandChina(loadIpData(ip));
return isBlockedIpRegion(loadIpData(ip));
}
private boolean isZoneValidationFailed(String reqZone) {
@ -235,6 +241,10 @@ public class LoginAccessValidationService {
};
}
static boolean isBlockedIpRegion(JSONObject dataObject) {
return isMainlandChina(dataObject) || isBlockedCountryOrRegion(dataObject);
}
static boolean isMainlandChina(JSONObject dataObject) {
if (dataObject == null) {
return false;
@ -251,6 +261,20 @@ public class LoginAccessValidationService {
return StringUtils.isBlank(region) || !ALLOWED_CHINA_REGIONS.contains(region);
}
private static boolean isBlockedCountryOrRegion(JSONObject dataObject) {
if (dataObject == null) {
return false;
}
String countryCode = dataObject.getString("country_id");
if (StringUtils.isNotBlank(countryCode)
&& BLOCKED_COUNTRY_CODES.contains(countryCode.trim().toUpperCase(Locale.ROOT))) {
return true;
}
String country = dataObject.getString("country");
String region = dataObject.getString("region");
return BLOCKED_COUNTRY_NAMES.contains(country) || BLOCKED_COUNTRY_NAMES.contains(region);
}
private static JSONObject normalizeIpNcGy(String provider, JSONObject jsonObject) {
JSONObject countryObject = jsonObject.getJSONObject("country");
if (countryObject == null) {

View File

@ -70,11 +70,39 @@ public class LoginAccessValidationServiceTest {
}
@Test
public void allowChinaSpecialRegions() {
public void blockHongKongRegion() {
JSONObject data = JSON.parseObject("""
{"country_id":"CN","country":"中国","region":"香港"}
""");
assertFalse(LoginAccessValidationService.isMainlandChina(data));
assertTrue(LoginAccessValidationService.isBlockedIpRegion(data));
}
@Test
public void blockMacauCountryCode() {
JSONObject data = JSON.parseObject("""
{"country_id":"MO","country":"Macao","region":""}
""");
assertTrue(LoginAccessValidationService.isBlockedIpRegion(data));
}
@Test
public void blockSingaporeCountryCode() {
JSONObject data = JSON.parseObject("""
{"country_id":"SG","country":"Singapore","region":""}
""");
assertTrue(LoginAccessValidationService.isBlockedIpRegion(data));
}
@Test
public void allowTaiwanRegion() {
JSONObject data = JSON.parseObject("""
{"country_id":"CN","country":"中国","region":"台湾"}
""");
assertFalse(LoginAccessValidationService.isBlockedIpRegion(data));
}
}

View File

@ -336,8 +336,10 @@ public class LoginLoggerListener implements MessageListener {
return LoginBlockResult.notBlocked();
}
List<String> reasons = new ArrayList<>();
if (IpCountryUtils.isMainlandChina(ipGeoData)) {
reasons.add("中国大陆IP");
if (IpCountryUtils.isBlockedIpRegion(ipGeoData)) {
reasons.add(IpCountryUtils.isMainlandChina(ipGeoData)
? "中国大陆IP"
: "受限IP地区:" + blockedRegionName(ipGeoData));
}
if (Objects.equals("Asia/Shanghai", event.getZoneId())) {
reasons.add("中国时区");
@ -347,6 +349,22 @@ public class LoginLoggerListener implements MessageListener {
: new LoginBlockResult(true, String.join(",", reasons));
}
private String blockedRegionName(IpCountryUtils.IpGeoData ipGeoData) {
if (Objects.isNull(ipGeoData) || ipGeoData.isEmpty()) {
return "";
}
if (StringUtils.isNotBlank(ipGeoData.region())) {
return ipGeoData.region();
}
if (StringUtils.isNotBlank(ipGeoData.countryName())) {
return ipGeoData.countryName();
}
if (StringUtils.isNotBlank(ipGeoData.countryCode())) {
return ipGeoData.countryCode();
}
return ipGeoData.region();
}
private boolean isLoginWhiteAccount(LoginLoggerEvent event, UserProfile userProfile) {
if (Objects.isNull(userProfile) || StringUtils.isBlank(userProfile.getAccount())) {
return false;

View File

@ -31,6 +31,12 @@ public class IpCountryUtils {
private static final List<String> ALLOWED_CHINA_REGIONS = List.of(
"香港", "澳门", "澳門", "台湾", "台灣", "Hong Kong", "Macau", "Macao", "Taiwan"
);
private static final List<String> BLOCKED_COUNTRY_CODES = List.of(
"HK", "MO", "SG"
);
private static final List<String> BLOCKED_COUNTRY_NAMES = List.of(
"香港", "澳门", "澳門", "Hong Kong", "Macau", "Macao", "新加坡", "Singapore"
);
private static final List<IpGeoProvider> IP_GEO_PROVIDERS = List.of(
new IpGeoProvider("ip.sb", "https://api.ip.sb/geoip/%s"),
new IpGeoProvider("freeipapi", "https://freeipapi.com/api/json/%s"),
@ -95,6 +101,10 @@ public class IpCountryUtils {
return isMainlandChina(getGeoData(ip));
}
public static boolean isBlockedIpRegion(IpGeoData data) {
return isMainlandChina(data) || isBlockedCountryOrRegion(data);
}
public static boolean isMainlandChina(IpGeoData data) {
if (data == null || data.isEmpty()) {
return false;
@ -108,6 +118,18 @@ public class IpCountryUtils {
return StringUtils.isBlank(data.region()) || !ALLOWED_CHINA_REGIONS.contains(data.region());
}
private static boolean isBlockedCountryOrRegion(IpGeoData data) {
if (data == null || data.isEmpty()) {
return false;
}
if (StringUtils.isNotBlank(data.countryCode())
&& BLOCKED_COUNTRY_CODES.contains(data.countryCode().trim().toUpperCase(Locale.ROOT))) {
return true;
}
return BLOCKED_COUNTRY_NAMES.contains(data.countryName())
|| BLOCKED_COUNTRY_NAMES.contains(data.region());
}
private IpGeoData requestIpGeoData(CloseableHttpClient httpClient, IpGeoProvider provider, String ip) {
String requestUrl = provider.buildUrl(ip);
HttpGet httpGet = new HttpGet(requestUrl);

View File

@ -69,9 +69,31 @@ public class IpCountryUtilsTest {
}
@Test
public void allowChinaSpecialRegions() {
public void blockHongKongRegion() {
IpCountryUtils.IpGeoData data = new IpCountryUtils.IpGeoData("CN", "中国", "香港", "test");
assertFalse(IpCountryUtils.isMainlandChina(data));
assertTrue(IpCountryUtils.isBlockedIpRegion(data));
}
@Test
public void blockMacauCountryCode() {
IpCountryUtils.IpGeoData data = new IpCountryUtils.IpGeoData("MO", "Macao", "", "test");
assertTrue(IpCountryUtils.isBlockedIpRegion(data));
}
@Test
public void blockSingaporeCountryCode() {
IpCountryUtils.IpGeoData data = new IpCountryUtils.IpGeoData("SG", "Singapore", "", "test");
assertTrue(IpCountryUtils.isBlockedIpRegion(data));
}
@Test
public void allowTaiwanRegion() {
IpCountryUtils.IpGeoData data = new IpCountryUtils.IpGeoData("CN", "中国", "台湾", "test");
assertFalse(IpCountryUtils.isBlockedIpRegion(data));
}
}