diff --git a/maxkey-authentications/maxkey-authentication-ip2location/build.gradle b/maxkey-authentications/maxkey-authentication-ip2location/build.gradle new file mode 100644 index 00000000..b6bae3f5 --- /dev/null +++ b/maxkey-authentications/maxkey-authentication-ip2location/build.gradle @@ -0,0 +1,12 @@ + +description = "maxkey-authentication-core" + + +dependencies { + //local jars + implementation fileTree(dir: '../maxkey-lib/', include: '*/*.jar') + + implementation project(":maxkey-common") + implementation project(":maxkey-core") + +} \ No newline at end of file diff --git a/maxkey-authentications/maxkey-authentication-ip2location/src/main/java/org/dromara/maxkey/autoconfigure/IpLocationAutoConfiguration.java b/maxkey-authentications/maxkey-authentication-ip2location/src/main/java/org/dromara/maxkey/autoconfigure/IpLocationAutoConfiguration.java new file mode 100644 index 00000000..4952511b --- /dev/null +++ b/maxkey-authentications/maxkey-authentication-ip2location/src/main/java/org/dromara/maxkey/autoconfigure/IpLocationAutoConfiguration.java @@ -0,0 +1,141 @@ +/* + * Copyright [2023] [MaxKey of copyright http://www.maxkey.top] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.dromara.maxkey.autoconfigure; + +import org.dromara.maxkey.ip2location.IpLocation; +import org.dromara.maxkey.ip2location.IpLocationParser; +import org.dromara.maxkey.ip2location.offline.GeoIP2V4; +import org.dromara.maxkey.ip2location.offline.Ip2regionV2; +import org.dromara.maxkey.ip2location.online.Ip138; +import org.lionsoul.ip2region.xdb.Searcher; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.core.io.ClassPathResource; +import org.springframework.util.StreamUtils; + +import com.maxmind.geoip2.DatabaseReader; + +/** + * + * @author Crystal.Sea + * + */ + +@AutoConfiguration +public class IpLocationAutoConfiguration implements InitializingBean { + static final Logger _logger = LoggerFactory.getLogger(IpLocationAutoConfiguration.class); + + /** + * 加载Ip2Region离线库数据 version 2.7.0 + * @return Ip2regionV2 + * @throws Exception + */ + public Ip2regionV2 ip2regionV2() throws Exception { + _logger.debug("IpRegion OffLine init..."); + ClassPathResource resource = new ClassPathResource("/ip2region/ip2region.xdb"); + byte[] dbBinStr = StreamUtils.copyToByteArray(resource.getInputStream()); + _logger.debug("ip2region length {}",dbBinStr.length); + Searcher searcher = Searcher.newWithBuffer(dbBinStr); + return new Ip2regionV2(searcher); + } + + + /** + * 加载GeoIP2离线库数据 version 4.0.1 + * @return GeoIp2V4 + * @throws Exception + */ + public GeoIP2V4 geoIP2() throws Exception { + _logger.debug("GeoIP2 OffLine init..."); + ClassPathResource resource = new ClassPathResource("/geoip2/GeoLite2-City.mmdb"); + DatabaseReader databaseReader = new DatabaseReader.Builder(resource.getInputStream()).build(); + return new GeoIP2V4(databaseReader); + } + + /** + * builder offline provider IpLocation + * @param offlineProvider + * @return IpLocation + */ + public IpLocation builderOfflineProvider(String offlineProvider) { + IpLocation ipLocationOffLine = null; + try { + if(offlineProvider.equalsIgnoreCase("none")) { + //do nothing + _logger.debug("IpLocation offline Provider none"); + }else if(offlineProvider.equalsIgnoreCase("Ip2Region")){ + ipLocationOffLine = ip2regionV2(); + _logger.debug("IpLocation offline Provider Ip2Region"); + }else if(offlineProvider.equalsIgnoreCase("GeoIp2")){ + ipLocationOffLine = geoIP2(); + _logger.debug("IpLocation offline Provider GeoIp2"); + } + }catch(Exception e) { + _logger.error("builder Offline IpLocation error", e); + } + return ipLocationOffLine; + } + + /** + * builder Online Provider IpLocation + * @param onlineProvider + * @return IpLocation + */ + public IpLocation builderOnlineProvider(String onlineProvider) { + //need on line provider + IpLocation ipLocationOnLine = null; + if(onlineProvider.equalsIgnoreCase("none")) { + //do nothing + _logger.debug("IpLocation online Provider none"); + }else if(onlineProvider.equalsIgnoreCase("Ip138")){ + ipLocationOnLine = new Ip138(); + _logger.debug("IpLocation online Provider Ip138"); + } + return ipLocationOnLine; + } + + /** + * IP转换区域地址解析 + * @param isIplocation 是否转换 + * @param onlineProvider 在线转换实现提供商none/Ip138/Ipchaxun + * @param offlineProvider 离线转换实现提供商none/Ip2Region/GeoIp2 + * @return IpLocationParser + * @throws Exception + */ + @Bean + public IpLocationParser ipLocationParser( + @Value("${maxkey.login.iplocation:false}") boolean isIplocation, + @Value("${maxkey.login.iplocation.online.provider:none}") String onlineProvider, + @Value("${maxkey.login.iplocation.offline.provider:none}") String offlineProvider) throws Exception { + return new IpLocationParser( + isIplocation, + builderOnlineProvider(onlineProvider), + builderOfflineProvider(offlineProvider) + ); + } + + @Override + public void afterPropertiesSet() throws Exception { + + } + +} diff --git a/maxkey-authentications/maxkey-authentication-ip2location/src/main/java/org/dromara/maxkey/ip2location/AbstractIpLocation.java b/maxkey-authentications/maxkey-authentication-ip2location/src/main/java/org/dromara/maxkey/ip2location/AbstractIpLocation.java new file mode 100644 index 00000000..d89650eb --- /dev/null +++ b/maxkey-authentications/maxkey-authentication-ip2location/src/main/java/org/dromara/maxkey/ip2location/AbstractIpLocation.java @@ -0,0 +1,50 @@ +package org.dromara.maxkey.ip2location; +/* + * Copyright [2023] [MaxKey of copyright http://www.maxkey.top] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + + +/** + * IpRegion转换抽象类,获取地址Location + * + * @author Crystal.Sea + * + */ +public abstract class AbstractIpLocation implements IpLocation{ + + int failCount = 0; + + public int getFailCount() { + return failCount; + }; + + public int plusFailCount() { + return failCount++; + }; + + + public String getLocation(String region) { + if(region.endsWith("电信") || region.endsWith("移动") || region.endsWith("联通")) { + region.substring(0, region.length() - 2).trim(); + } + + if(region.indexOf(" ") > 0) { + return region.split(" ")[0]; + } + + return region; + } +} diff --git a/maxkey-authentications/maxkey-authentication-ip2location/src/main/java/org/dromara/maxkey/ip2location/IpLocation.java b/maxkey-authentications/maxkey-authentication-ip2location/src/main/java/org/dromara/maxkey/ip2location/IpLocation.java new file mode 100644 index 00000000..808ab816 --- /dev/null +++ b/maxkey-authentications/maxkey-authentication-ip2location/src/main/java/org/dromara/maxkey/ip2location/IpLocation.java @@ -0,0 +1,39 @@ +package org.dromara.maxkey.ip2location; +/* + * Copyright [2023] [MaxKey of copyright http://www.maxkey.top] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + + +/** + * IpRegion转换接口 + * + * @author Crystal.Sea + * + */ +public interface IpLocation { + public static final String USERAGENT = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.82 Safari/537.36"; + + public static final int TIMEOUT = 5000; + + public Region region(String ipAddress); + + public String getLocation(String region); + + public int getFailCount(); + + public int plusFailCount() ; + +} diff --git a/maxkey-authentications/maxkey-authentication-ip2location/src/main/java/org/dromara/maxkey/ip2location/IpLocationLocal.java b/maxkey-authentications/maxkey-authentication-ip2location/src/main/java/org/dromara/maxkey/ip2location/IpLocationLocal.java new file mode 100644 index 00000000..fca29a40 --- /dev/null +++ b/maxkey-authentications/maxkey-authentication-ip2location/src/main/java/org/dromara/maxkey/ip2location/IpLocationLocal.java @@ -0,0 +1,35 @@ +package org.dromara.maxkey.ip2location; +/* + * Copyright [2023] [MaxKey of copyright http://www.maxkey.top] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + + +/** + * 本地(127.0.0.1/0:0:0:0:0:0:0:1)地址 + * + * @author Crystal.Sea + * + */ +public class IpLocationLocal extends AbstractIpLocation implements IpLocation{ + + @Override + public Region region(String ipAddress) { + if(ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")) { + return new Region("local"); + } + return null; + } +} diff --git a/maxkey-authentications/maxkey-authentication-ip2location/src/main/java/org/dromara/maxkey/ip2location/IpLocationParser.java b/maxkey-authentications/maxkey-authentication-ip2location/src/main/java/org/dromara/maxkey/ip2location/IpLocationParser.java new file mode 100644 index 00000000..4a07fc16 --- /dev/null +++ b/maxkey-authentications/maxkey-authentication-ip2location/src/main/java/org/dromara/maxkey/ip2location/IpLocationParser.java @@ -0,0 +1,73 @@ +package org.dromara.maxkey.ip2location; +/* + * Copyright [2023] [MaxKey of copyright http://www.maxkey.top] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * IP转换区域地址解析 + * + *
+ * 依次顺序为Local(本地) ->OnLine(在线解析) ->OffLine(离线解析) -> unknown(未知) + *
+ * + * @author Crystal.Sea + * + */ +public class IpLocationParser extends AbstractIpLocation implements IpLocation{ + + IpLocation ipRegionLocal = new IpLocationLocal(); + + IpLocation ipLocationOnLine; + + IpLocation ipLocationOffLine; + + boolean isIpLocation; + + + public IpLocationParser() { + } + + + public IpLocationParser(boolean isIpLocation,IpLocation ipLocationOnLine, IpLocation ipLocationOffLine) { + super(); + this.ipLocationOnLine = ipLocationOnLine; + this.ipLocationOffLine = ipLocationOffLine; + this.isIpLocation = isIpLocation; + } + + /** + * ip转换区域地址 + */ + @Override + public Region region(String ipAddress) { + Region region = null; + if( isIpLocation ){//true 需要转换,否则跳过 + //本地转换 + region = ipRegionLocal.region(ipAddress); + //在线转换 + if(ipLocationOnLine != null && region == null) { + region = ipLocationOnLine.region(ipAddress); + } + //离线转换 + if(ipLocationOffLine != null && region == null) { + region = ipLocationOffLine.region(ipAddress); + } + } + //不转换或者未找到返回unknown + return region == null ? new Region("unknown") : region; + } + + +} diff --git a/maxkey-authentications/maxkey-authentication-ip2location/src/main/java/org/dromara/maxkey/ip2location/Region.java b/maxkey-authentications/maxkey-authentication-ip2location/src/main/java/org/dromara/maxkey/ip2location/Region.java new file mode 100644 index 00000000..3dc9d37d --- /dev/null +++ b/maxkey-authentications/maxkey-authentication-ip2location/src/main/java/org/dromara/maxkey/ip2location/Region.java @@ -0,0 +1,111 @@ +/* + * Copyright [2023] [MaxKey of copyright http://www.maxkey.top] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.dromara.maxkey.ip2location; + +/** + * IP所属区域实体 + * + * @author Crystal.sea + * + */ +public class Region { + + /** + * 国家 + */ + String country; + + /** + * 省/州 + */ + String province; + + /** + * 城市 + */ + String city; + + /** + * 区域位置 + */ + String addr; + + public Region() { + + } + + public Region(String addr) { + this.addr = addr; + } + + public Region(String country, String province, String city, String addr) { + super(); + this.country = country; + this.province = province; + this.city = city; + this.addr = addr; + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } + + public String getProvince() { + return province; + } + + public void setProvince(String province) { + this.province = province; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getAddr() { + return addr; + } + + public void setAddr(String addr) { + this.addr = addr; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("Region [country="); + builder.append(country); + builder.append(", province="); + builder.append(province); + builder.append(", city="); + builder.append(city); + builder.append(", addr="); + builder.append(addr); + builder.append("]"); + return builder.toString(); + } + +} diff --git a/maxkey-authentications/maxkey-authentication-ip2location/src/main/java/org/dromara/maxkey/ip2location/offline/GeoIP2V4.java b/maxkey-authentications/maxkey-authentication-ip2location/src/main/java/org/dromara/maxkey/ip2location/offline/GeoIP2V4.java new file mode 100644 index 00000000..3f3726db --- /dev/null +++ b/maxkey-authentications/maxkey-authentication-ip2location/src/main/java/org/dromara/maxkey/ip2location/offline/GeoIP2V4.java @@ -0,0 +1,57 @@ +/* + * Copyright [2023] [MaxKey of copyright http://www.maxkey.top] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dromara.maxkey.ip2location.offline; + +import java.io.IOException; +import java.net.InetAddress; + +import org.dromara.maxkey.ip2location.AbstractIpLocation; +import org.dromara.maxkey.ip2location.IpLocation; +import org.dromara.maxkey.ip2location.Region; + +import com.maxmind.geoip2.DatabaseReader; +import com.maxmind.geoip2.exception.GeoIp2Exception; +import com.maxmind.geoip2.model.CityResponse; + +public class GeoIP2V4 extends AbstractIpLocation implements IpLocation{ + + DatabaseReader databaseReader; + + public GeoIP2V4(DatabaseReader databaseReader) { + this.databaseReader = databaseReader; + } + + @Override + public Region region(String ipAddress) { + try { + //解析IP地址 + InetAddress inetAddress = InetAddress.getByName(ipAddress); + // 获取查询结果 + CityResponse response = databaseReader.city(inetAddress); + // 获取国家信息 + String country = response.getCountry().getNames().get("zh-CN"); + // 获取省份/州 + String state = response.getMostSpecificSubdivision().getNames().get("zh-CN"); + // 获取城市 + String city = response.getCity().getNames().get("zh-CN"); + return new Region(country , state , city , country +" " + state + " " + city); + } catch (IOException | GeoIp2Exception e) { + e.printStackTrace(); + } + return null; + } + +} diff --git a/maxkey-authentications/maxkey-authentication-ip2location/src/main/java/org/dromara/maxkey/ip2location/offline/Ip2regionV2.java b/maxkey-authentications/maxkey-authentication-ip2location/src/main/java/org/dromara/maxkey/ip2location/offline/Ip2regionV2.java new file mode 100644 index 00000000..004e8654 --- /dev/null +++ b/maxkey-authentications/maxkey-authentication-ip2location/src/main/java/org/dromara/maxkey/ip2location/offline/Ip2regionV2.java @@ -0,0 +1,61 @@ +/* + * Copyright [2023] [MaxKey of copyright http://www.maxkey.top] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dromara.maxkey.ip2location.offline; + +import org.dromara.maxkey.ip2location.AbstractIpLocation; +import org.dromara.maxkey.ip2location.IpLocation; +import org.dromara.maxkey.ip2location.Region; +import org.lionsoul.ip2region.xdb.Searcher; + + +/** + * 基于ip2region离线库ip查询 + * + *+ * 官方文档:https://gitee.com/lionsoul/ip2region Apache-2.0 + *
+ * + *+ * Ip2region (2.0 - xdb) 是一个离线 IP 数据管理框架和定位库,支持亿级别的数据段,10微秒级别的查询性能,提供了许多主流编程语言的 xdb 数据管理引擎的实现。 + *
+ * + * @author Crystal.Sea + * + */ +public class Ip2regionV2 extends AbstractIpLocation implements IpLocation{ + + Searcher searcher;; + + public Ip2regionV2(Searcher searcher) { + this.searcher = searcher; + } + + @Override + public Region region(String ipAddress) { + try { + String regionAddr = searcher.search(ipAddress); + if(regionAddr.indexOf("内网IP")>-1) { + return new Region("内网IP"); + } + String[] regionAddrs =regionAddr.split("\\|"); + return new Region(regionAddrs[0],regionAddrs[2],regionAddrs[3],regionAddrs[0]+regionAddrs[2]+regionAddrs[3]); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + +} diff --git a/maxkey-authentications/maxkey-authentication-ip2location/src/main/java/org/dromara/maxkey/ip2location/online/Ip138.java b/maxkey-authentications/maxkey-authentication-ip2location/src/main/java/org/dromara/maxkey/ip2location/online/Ip138.java new file mode 100644 index 00000000..f6c8ffe0 --- /dev/null +++ b/maxkey-authentications/maxkey-authentication-ip2location/src/main/java/org/dromara/maxkey/ip2location/online/Ip138.java @@ -0,0 +1,61 @@ +/* + * Copyright [2023] [MaxKey of copyright http://www.maxkey.top] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dromara.maxkey.ip2location.online; + +import java.io.IOException; + +import org.dromara.maxkey.ip2location.AbstractIpLocation; +import org.dromara.maxkey.ip2location.IpLocation; +import org.dromara.maxkey.ip2location.Region; +import org.dromara.maxkey.util.JsonUtils; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; + +/** + * Ip138查询ip地址 + * + * @author Crystal.Sea + * + */ +public class Ip138 extends AbstractIpLocation implements IpLocation{ + + public static final String REGION_URL = "https://www.ip138.com/iplookup.asp?ip=%s&action=2"; + + public static final String BEGIN = "\"ip_c_list\":["; + public static final String END = "], \"zg\":1};"; + + @Override + public Region region(String ipAddress) { + try { + Document doc; + doc = Jsoup.connect(String.format(REGION_URL, ipAddress)) + .timeout(TIMEOUT) + .userAgent(USERAGENT) + .header("Host", "www.ip138.com") + .header("Referer", "https://www.ip138.com/") + .header("sec-ch-ua", "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"98\", \"Google Chrome\";v=\"98\"") + .header("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9") + .get(); + String htmlData = doc.toString(); + String jsonData = htmlData.substring(htmlData.indexOf(BEGIN) + BEGIN.length() , htmlData.indexOf(END)); + Ip138Response response = JsonUtils.stringToObject(jsonData, Ip138Response.class); + return response == null ? null : new Region(response.getCt(),response.getProv(),response.getCity(),getLocation(response.toString())); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/maxkey-authentications/maxkey-authentication-ip2location/src/main/java/org/dromara/maxkey/ip2location/online/Ip138Response.java b/maxkey-authentications/maxkey-authentication-ip2location/src/main/java/org/dromara/maxkey/ip2location/online/Ip138Response.java new file mode 100644 index 00000000..994febaa --- /dev/null +++ b/maxkey-authentications/maxkey-authentication-ip2location/src/main/java/org/dromara/maxkey/ip2location/online/Ip138Response.java @@ -0,0 +1,81 @@ +/* + * Copyright [2023] [MaxKey of copyright http://www.maxkey.top] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dromara.maxkey.ip2location.online; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +/** + * Ip138返回结果 + * + * @author Crystal.Sea + * + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class Ip138Response { + + String ct; + String prov; + String city; + String area; + String yunyin; + + public Ip138Response() { + } + public String getCt() { + return ct; + } + public void setCt(String ct) { + this.ct = ct; + } + public String getProv() { + return prov; + } + public void setProv(String prov) { + this.prov = prov; + } + public String getCity() { + return city; + } + public void setCity(String city) { + this.city = city; + } + public String getArea() { + return area; + } + public void setArea(String area) { + this.area = area; + } + public String getYunyin() { + return yunyin; + } + public void setYunyin(String yunyin) { + this.yunyin = yunyin; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append(ct) + .append(prov) + .append(city) + .append(area) + .append(" ") + .append(yunyin); + return builder.toString(); + } + + +} diff --git a/maxkey-authentications/maxkey-authentication-ip2location/src/main/resources/geoip2/COPYRIGHT.txt b/maxkey-authentications/maxkey-authentication-ip2location/src/main/resources/geoip2/COPYRIGHT.txt new file mode 100644 index 00000000..1f9e44a7 --- /dev/null +++ b/maxkey-authentications/maxkey-authentication-ip2location/src/main/resources/geoip2/COPYRIGHT.txt @@ -0,0 +1 @@ +Database and Contents Copyright (c) 2022 MaxMind, Inc. diff --git a/maxkey-authentications/maxkey-authentication-ip2location/src/main/resources/geoip2/GeoLite2-City.mmdb b/maxkey-authentications/maxkey-authentication-ip2location/src/main/resources/geoip2/GeoLite2-City.mmdb new file mode 100644 index 00000000..0ddbb2be Binary files /dev/null and b/maxkey-authentications/maxkey-authentication-ip2location/src/main/resources/geoip2/GeoLite2-City.mmdb differ diff --git a/maxkey-authentications/maxkey-authentication-ip2location/src/main/resources/geoip2/LICENSE.txt b/maxkey-authentications/maxkey-authentication-ip2location/src/main/resources/geoip2/LICENSE.txt new file mode 100644 index 00000000..ee7434dc --- /dev/null +++ b/maxkey-authentications/maxkey-authentication-ip2location/src/main/resources/geoip2/LICENSE.txt @@ -0,0 +1,3 @@ +Use of this MaxMind product is governed by MaxMind's GeoLite2 End User License Agreement, which can be viewed at https://www.maxmind.com/en/geolite2/eula. + +This database incorporates GeoNames [https://www.geonames.org] geographical data, which is made available under the Creative Commons Attribution 4.0 License. To view a copy of this license, visit https://creativecommons.org/licenses/by/4.0/. diff --git a/maxkey-authentications/maxkey-authentication-ip2location/src/main/resources/geoip2/README.txt b/maxkey-authentications/maxkey-authentication-ip2location/src/main/resources/geoip2/README.txt new file mode 100644 index 00000000..16e29adb --- /dev/null +++ b/maxkey-authentications/maxkey-authentication-ip2location/src/main/resources/geoip2/README.txt @@ -0,0 +1 @@ +Latitude and longitude are not precise and should not be used to identify a particular street address or household. diff --git a/maxkey-authentications/maxkey-authentication-ip2location/src/main/resources/ip2region/ip2region.xdb b/maxkey-authentications/maxkey-authentication-ip2location/src/main/resources/ip2region/ip2region.xdb new file mode 100644 index 00000000..c78b7928 Binary files /dev/null and b/maxkey-authentications/maxkey-authentication-ip2location/src/main/resources/ip2region/ip2region.xdb differ diff --git a/maxkey-authentications/maxkey-authentication-ip2location/src/test/java/org/dromara/maxkey/ip2location/Geoip2Test.java b/maxkey-authentications/maxkey-authentication-ip2location/src/test/java/org/dromara/maxkey/ip2location/Geoip2Test.java new file mode 100644 index 00000000..67a5cb6c --- /dev/null +++ b/maxkey-authentications/maxkey-authentication-ip2location/src/test/java/org/dromara/maxkey/ip2location/Geoip2Test.java @@ -0,0 +1,66 @@ +/* + * Copyright [2023] [MaxKey of copyright http://www.maxkey.top] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dromara.maxkey.ip2location; + +import java.io.IOException; +import java.net.InetAddress; + +import org.springframework.core.io.ClassPathResource; + +import com.maxmind.geoip2.DatabaseReader; +import com.maxmind.geoip2.exception.GeoIp2Exception; +import com.maxmind.geoip2.model.CityResponse; + +public class Geoip2Test { + + public static void main(String[] args) throws IOException { + // TODO Auto-generated method stub + ClassPathResource resource = new ClassPathResource("/geoip2/GeoLite2-City.mmdb"); + String ip = "117.155.70.59"; + + if (!resource.getFile().exists()) { + System.out.println("Error: Invalid GeoLite2-City.mmdb file, filePath:" + resource.getFile().getPath()); + + } + // 读取数据库内容 + DatabaseReader reader = null; + try { + reader = new DatabaseReader.Builder(resource.getFile()).build(); + //解析IP地址 + InetAddress ipAddress = InetAddress.getByName(ip); + // 获取查询结果 + CityResponse response = reader.city(ipAddress); + // 获取国家信息 + String country = response.getCountry().getNames().get("zh-CN"); + // 获取省份 + String state = response.getMostSpecificSubdivision().getNames().get("zh-CN"); + //查询不到时保持与ip2region方式的返回结果一致 + if (state == null){ + state = "0"; + } + // 获取城市 + String city = response.getCity().getNames().get("zh-CN"); + if (city == null){ + city = "0"; + } + String[] resu = {state,city}; + System.out.println(" " +country+" " +state +" " +city); + } catch (IOException | GeoIp2Exception e) { + e.printStackTrace(); + } + } + +} diff --git a/maxkey-authentications/maxkey-authentication-ip2location/src/test/java/org/dromara/maxkey/ip2location/Ip2RegionV2Test.java b/maxkey-authentications/maxkey-authentication-ip2location/src/test/java/org/dromara/maxkey/ip2location/Ip2RegionV2Test.java new file mode 100644 index 00000000..b6a14c32 --- /dev/null +++ b/maxkey-authentications/maxkey-authentication-ip2location/src/test/java/org/dromara/maxkey/ip2location/Ip2RegionV2Test.java @@ -0,0 +1,40 @@ +/* + * Copyright [2022] [MaxKey of copyright http://www.maxkey.top] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.dromara.maxkey.ip2location; + +import org.dromara.maxkey.ip2location.offline.Ip2regionV2; +import org.lionsoul.ip2region.xdb.Searcher; +import org.springframework.core.io.ClassPathResource; +import org.springframework.util.StreamUtils; + +public class Ip2RegionV2Test { + + public static void main(String[] args) throws Exception { + // TODO Auto-generated method stub + String ip ="101.227.131.220"; + ClassPathResource resource = new ClassPathResource("/ip2region/ip2region.xdb"); + byte[] dbBinStr = StreamUtils.copyToByteArray(resource.getInputStream()); + System.out.println(dbBinStr.length); + //_logger.debug("ip2region length {}",dbBinStr.length); + Searcher searcher = Searcher.newWithBuffer(dbBinStr); + Ip2regionV2 ipRegionV2OffLine = new Ip2regionV2(searcher); + String region = ipRegionV2OffLine.region(ip).toString(); + System.out.println(region); + + } +} diff --git a/maxkey-authentications/maxkey-authentication-ip2location/src/test/java/org/dromara/maxkey/ip2location/IpRegionIp138Test.java b/maxkey-authentications/maxkey-authentication-ip2location/src/test/java/org/dromara/maxkey/ip2location/IpRegionIp138Test.java new file mode 100644 index 00000000..90282a54 --- /dev/null +++ b/maxkey-authentications/maxkey-authentication-ip2location/src/test/java/org/dromara/maxkey/ip2location/IpRegionIp138Test.java @@ -0,0 +1,32 @@ +/* + * Copyright [2023] [MaxKey of copyright http://www.maxkey.top] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.dromara.maxkey.ip2location; + + +import org.dromara.maxkey.ip2location.IpLocation; +import org.dromara.maxkey.ip2location.online.Ip138; +import org.junit.Test; + +public class IpRegionIp138Test { + + @Test + public void test(){ + IpLocation ipRegion = new Ip138(); + System.out.println(ipRegion.region("117.155.70.59")); + } + +} diff --git a/maxkey-authentications/maxkey-authentication-ip2location/src/test/java/org/dromara/maxkey/ip2location/IpRegionParserTest.java b/maxkey-authentications/maxkey-authentication-ip2location/src/test/java/org/dromara/maxkey/ip2location/IpRegionParserTest.java new file mode 100644 index 00000000..35533503 --- /dev/null +++ b/maxkey-authentications/maxkey-authentication-ip2location/src/test/java/org/dromara/maxkey/ip2location/IpRegionParserTest.java @@ -0,0 +1,34 @@ +/* + * Copyright [2023] [MaxKey of copyright http://www.maxkey.top] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dromara.maxkey.ip2location; + +import org.dromara.maxkey.ip2location.IpLocationParser; +import org.dromara.maxkey.ip2location.online.Ip138; +import org.junit.Test; + +public class IpRegionParserTest { + + @Test + public void test(){ + System.out.println( + new IpLocationParser().region("127.0.0.1") + ); + + System.out.println( + new IpLocationParser(true,new Ip138(),null).region("117.155.70.59") + ); + } +} diff --git a/settings.gradle b/settings.gradle index 962060f1..39729439 100644 --- a/settings.gradle +++ b/settings.gradle @@ -28,6 +28,7 @@ include ( //authentications 'maxkey-authentications:maxkey-authentication-core', 'maxkey-authentications:maxkey-authentication-captcha', + 'maxkey-authentications:maxkey-authentication-ip2location', 'maxkey-authentications:maxkey-authentication-social', 'maxkey-authentications:maxkey-authentication-otp', 'maxkey-authentications:maxkey-authentication-provider',