Skip to content

Commit e61724b

Browse files
committed
Initial commit
0 parents  commit e61724b

File tree

8 files changed

+405
-0
lines changed

8 files changed

+405
-0
lines changed

Diff for: .gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/.idea
2+
/out
3+
/target
4+

Diff for: README.md

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
## 基于ip的访问控制(ip黑名单、ip白名单)
2+
3+
### Usage:
4+
1. maven:
5+
- add repo:
6+
```text
7+
<repositories>
8+
<repository>
9+
<id>maven-repo-cc11001100</id>
10+
<url>https://raw.github.com/cc11001100/maven-repo/access-control-list-based-on-ip/</url>
11+
<snapshots>
12+
<enabled>true</enabled>
13+
<updatePolicy>always</updatePolicy>
14+
</snapshots>
15+
</repository>
16+
</repositories>
17+
```
18+
- add dependency:
19+
```text
20+
<dependency>
21+
<groupId>cc11001100</groupId>
22+
<artifactId>access-control-list-based-on-ip</artifactId>
23+
<version>1.0-SNAPSHOT</version>
24+
</dependency>
25+
```
26+
2. code:
27+
```text
28+
// 黑名单
29+
//IpAcl acl = new IpAcl(IpAcl.AclType.BLACK_LIST);
30+
// 白名单
31+
IpAcl acl = new IpAcl(IpAcl.AclType.WHITE_LIST);
32+
33+
// 从配置文件初始化访问控制列表
34+
acl.readFromConfigFile("ip-list");
35+
// 手动添加,以追加的形式添加
36+
acl.add("192.168.2.15");
37+
acl.add(Arrays.asList("192.168.2.15", "192.168.1.20"));
38+
39+
// 检查ip是否允许访问
40+
System.out.println(acl.check("192.168.2.15")); // true
41+
42+
// 从访问控制列表中移除ip
43+
acl.remove("192.168.2.15");
44+
45+
// 检查ip是否允许访问
46+
System.out.println(acl.check("192.168.2.15")); // false
47+
```

Diff for: access-control-list-based-on-ip.iml

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<module type="JAVA_MODULE" version="4" />

Diff for: pom.xml

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<groupId>CC11001100</groupId>
8+
<artifactId>access-control-list-based-on-ip</artifactId>
9+
<version>1.0-SNAPSHOT</version>
10+
11+
<properties>
12+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
13+
<log4j2.version>2.6.2</log4j2.version>
14+
<github.global.server>github</github.global.server>
15+
</properties>
16+
17+
<build>
18+
<plugins>
19+
<plugin>
20+
<groupId>org.apache.maven.plugins</groupId>
21+
<artifactId>maven-compiler-plugin</artifactId>
22+
<configuration>
23+
<source>8</source>
24+
<target>8</target>
25+
</configuration>
26+
</plugin>
27+
<plugin>
28+
<artifactId>maven-deploy-plugin</artifactId>
29+
<version>2.8.1</version>
30+
<configuration>
31+
<altDeploymentRepository>internal.repo::default::file://${project.build.directory}/maven-repo
32+
</altDeploymentRepository>
33+
</configuration>
34+
</plugin>
35+
<plugin>
36+
<groupId>com.github.github</groupId>
37+
<artifactId>site-maven-plugin</artifactId>
38+
<version>0.12</version>
39+
<configuration>
40+
<message>Maven artifacts for ${project.version}</message>
41+
<noJekyll>true</noJekyll>
42+
<outputDirectory>${project.build.directory}/maven-repo</outputDirectory>
43+
<branch>refs/heads/access-control-list-based-on-ip</branch>
44+
<includes>
45+
<include>**/*</include>
46+
</includes>
47+
<repositoryName>maven-repo</repositoryName>
48+
<repositoryOwner>CC11001100</repositoryOwner>
49+
</configuration>
50+
<executions>
51+
<execution>
52+
<goals>
53+
<goal>site</goal>
54+
</goals>
55+
<phase>deploy</phase>
56+
</execution>
57+
</executions>
58+
</plugin>
59+
</plugins>
60+
</build>
61+
62+
63+
</project>

Diff for: src/main/java/cc11001100/acl/ip/IpAcl.java

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package cc11001100.acl.ip;
2+
3+
import java.io.BufferedReader;
4+
import java.io.IOException;
5+
import java.io.InputStreamReader;
6+
import java.util.ArrayList;
7+
import java.util.List;
8+
9+
/**
10+
* @author CC11001100
11+
*/
12+
public class IpAcl {
13+
14+
private List<IpRange> ipRangeList = new ArrayList<>();
15+
private AclType aclType;
16+
17+
public IpAcl(AclType aclType) {
18+
this.aclType = aclType;
19+
}
20+
21+
public void add(String line) {
22+
if (!isComment(line)) {
23+
ipRangeList.add(new IpRange(line));
24+
}
25+
}
26+
27+
public void add(List<String> lineList) {
28+
lineList.forEach(this::add);
29+
}
30+
31+
/**
32+
* 将某个ip从访问控制列表移除,必须完全匹配ipRange才可移除成功
33+
*
34+
* @param ipRangeNeedToRemove
35+
*/
36+
public void remove(String ipRangeNeedToRemove) {
37+
ipRangeList.removeIf(ipRange -> ipRange.getIpRange().equals(ipRangeNeedToRemove));
38+
}
39+
40+
public void readFromConfigFile(String configFilePath) {
41+
try {
42+
BufferedReader reader = new BufferedReader(new InputStreamReader(Thread.currentThread().getContextClassLoader().getResourceAsStream(configFilePath), "UTF-8"));
43+
String s = null;
44+
while ((s = reader.readLine()) != null) {
45+
// 使用#开头的行作为注释
46+
if (isComment(s)) {
47+
continue;
48+
}
49+
ipRangeList.add(new IpRange(s));
50+
}
51+
} catch (IOException e) {
52+
e.printStackTrace();
53+
}
54+
}
55+
56+
private boolean isComment(String s) {
57+
return s.startsWith("#");
58+
}
59+
60+
/**
61+
* @param ip 要检查的ip,比如192.168.1.1
62+
* @return 是否允许访问,true允许访问,false不允许访问
63+
*/
64+
public boolean check(String ip) {
65+
long ipLong = IpRange.ip2Long(ip);
66+
switch (aclType) {
67+
case WHITE_LIST:
68+
return whiteListCheck(ipLong);
69+
case BLACK_LIST:
70+
return blackListCheck(ipLong);
71+
default:
72+
throw new IllegalArgumentException("nonsupport type!");
73+
}
74+
}
75+
76+
private boolean blackListCheck(long ipLong) {
77+
for (IpRange ipRange : ipRangeList) {
78+
if (ipRange.inRange(ipLong)) {
79+
return false;
80+
}
81+
}
82+
return true;
83+
}
84+
85+
private boolean whiteListCheck(long ipLong) {
86+
for (IpRange ipRange : ipRangeList) {
87+
if (ipRange.inRange(ipLong)) {
88+
return true;
89+
}
90+
}
91+
return false;
92+
}
93+
94+
public enum AclType {
95+
// 白名单
96+
WHITE_LIST,
97+
// 黑名单
98+
BLACK_LIST;
99+
}
100+
101+
}

Diff for: src/main/java/cc11001100/acl/ip/IpRange.java

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package cc11001100.acl.ip;
2+
3+
import java.util.Objects;
4+
5+
import static java.lang.Long.parseLong;
6+
7+
/**
8+
* 用于ip检查,匹配子网或单个ip
9+
* <p>
10+
* 192.168.1.0/24
11+
* 192.168.1.10
12+
*
13+
* @author CC11001100
14+
*/
15+
public class IpRange {
16+
17+
private String ipRange;
18+
private long low;
19+
private long high;
20+
21+
public IpRange(String ipRange) {
22+
this.ipRange = ipRange;
23+
24+
String[] ss = ipRange.split("/");
25+
String ip = ss[0];
26+
long ipLong = ip2Long(ip);
27+
// 单个ip地址,比如192.168.1.15
28+
if (ss.length <= 1) {
29+
low = high = ipLong;
30+
} else {
31+
// ip网段,比如192.168.1.0/24
32+
long networkBitLength = parseLong(ss[1]);
33+
long hostBitLength = 32 - networkBitLength;
34+
long hostBitSetToOne = (1L << hostBitLength) - 1;
35+
high = ipLong | hostBitSetToOne;
36+
low = ipLong & (Long.MAX_VALUE ^ hostBitSetToOne);
37+
}
38+
}
39+
40+
public boolean inRange(String ip) {
41+
return inRange(ip2Long(ip));
42+
}
43+
44+
public boolean inRange(long ipLong) {
45+
return ipLong >= low && ipLong <= high;
46+
}
47+
48+
public static long ip2Long(String ip) {
49+
String[] ss = ip.split("\\.");
50+
return (parseLong(ss[0]) << 24) | (parseLong(ss[1]) << 16) | (parseLong(ss[2]) << 8) | parseLong(ss[3]);
51+
}
52+
53+
public static String long2Ip(long ipLong) {
54+
return Long.toString(ipLong >> 24) + "." + Long.toString(ipLong >> 16 & 0XFFL) +
55+
"." + Long.toString(ipLong >> 8 & 0XFFL) + "." + Long.toString(ipLong & 0XFFL);
56+
}
57+
58+
@Override
59+
public boolean equals(Object o) {
60+
if (this == o) return true;
61+
if (o == null || getClass() != o.getClass()) return false;
62+
IpRange ipRange1 = (IpRange) o;
63+
return low == ipRange1.low &&
64+
high == ipRange1.high &&
65+
Objects.equals(ipRange, ipRange1.ipRange);
66+
}
67+
68+
@Override
69+
public int hashCode() {
70+
return Objects.hash(ipRange, low, high);
71+
}
72+
73+
public String getIpRange() {
74+
return ipRange;
75+
}
76+
77+
public void setIpRange(String ipRange) {
78+
this.ipRange = ipRange;
79+
}
80+
81+
public long getLow() {
82+
return low;
83+
}
84+
85+
public void setLow(long low) {
86+
this.low = low;
87+
}
88+
89+
public long getHigh() {
90+
return high;
91+
}
92+
93+
public void setHigh(long high) {
94+
this.high = high;
95+
}
96+
97+
@Override
98+
public String toString() {
99+
return "IpRange{" +
100+
"ipRange='" + ipRange + '\'' +
101+
", low=" + low +
102+
", high=" + high +
103+
'}';
104+
}
105+
106+
}

Diff for: src/main/resources/ip-list

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
192.168.1.0/24
2+
8.8.8.8

0 commit comments

Comments
 (0)