因响应等保评级需求,后端管理登录需加入双因素验证,即:
账号+密码+手机验证码或账号+密码+IP白名单过滤
因为是应付整改需求,怎么简单怎么来,ip白名单只需要在后端增加一个校验工具类即可。
说下思路,在数据库动态配置ip白名单列表,格式类似于阿里云安全组,可为单个固定ip(xxx.xxx.xxx.xxx),或CIDR范围格式(xxx.xxx.0.0/16)。管理端登陆时,对访问ip进行白名单校验,在白名单范围内即可顺利登录,否则拦截。
工具类代码如下:
import java.util.*;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.net.Inet4Address;
import java.util.regex.PatternSyntaxException;
public class IPWhitelistChecker {
private List<String> whitelist;
private static Set<String> whiteSet = new HashSet<>(Arrays.asList(
"0:0:0:0:0:0:0:1",
"localhost",
"127.0.0.1"
));
public IPWhitelistChecker(List<String> whitelist) {
this.whitelist = whitelist;
}
public boolean isIPInWhitelist(String ipToCheck) {
if (whiteSet.contains(ipToCheck)){
return true;
}
try {
InetAddress ipAddress = InetAddress.getByName(ipToCheck);
if (ipAddress instanceof Inet4Address) {
for (String rule : whitelist) {
if (isValidIPRule(rule)) {
if (ipAddress.equals(InetAddress.getByName(rule))) {
return true;
}
} else if (isValidCIDRRule(rule)) {
if (isIPInCIDR(ipAddress, rule)) {
return true;
}
}
}
}
} catch (UnknownHostException e) {
}
return false;
}
private boolean isValidIPRule(String rule) {
try {
InetAddress.getByName(rule);
return true;
} catch (UnknownHostException e) {
return false;
}
}
private boolean isValidCIDRRule(String rule) {
try {
Pattern cidrPattern = Pattern.compile("^\\d+\\.\\d+\\.\\d+\\.\\d+\\/\\d+$");
Matcher matcher = cidrPattern.matcher(rule);
return matcher.matches();
} catch (PatternSyntaxException e) {
return false;
}
}
private boolean isIPInCIDR(InetAddress ipAddress, String cidrRule) {
try {
String[] parts = cidrRule.split("/");
String cidrAddress = parts[0];
int prefixLength = Integer.parseInt(parts[1]);
InetAddress cidrNetwork = InetAddress.getByName(cidrAddress);
byte[] ipBytes = ipAddress.getAddress();
byte[] networkBytes = cidrNetwork.getAddress();
if (ipBytes.length != networkBytes.length) {
return false;
}
for (int i = 0; i < prefixLength / 8; i++) {
if (ipBytes[i] != networkBytes[i]) {
return false;
}
}
int remainingBits = prefixLength % 8;
if (remainingBits > 0) {
int mask = 0xFF00 >> remainingBits;
if ((ipBytes[prefixLength / 8] & mask) != (networkBytes[prefixLength / 8] & mask)) {
return false;
}
}
return true;
} catch (UnknownHostException e) {
return false;
}
}
public static void main(String[] args) {
List<String> whitelist = new ArrayList<>();
whitelist.add("111.130.33.179");
whitelist.add("117.118.0.0/16");
IPWhitelistChecker checker = new IPWhitelistChecker(whitelist);
String ipToCheck = "111.130.33.179";
if (checker.isIPInWhitelist(ipToCheck)) {
System.out.println(ipToCheck + " 在白名单内");
} else {
System.out.println(ipToCheck + " 不在白名单内");
}
}
}