java web ip_详解Java Web如何限制访问的IP的两种方法
前一阵子因为在做项目时碰到了这个功能,现在好好总结一下,至于为什么要限制IP访问,我就不多说了。然后百度了一下,现在主要有两种方式去限制IP访问,第一种是最简单的方便的,第二种是通过过滤器来限制访问。下面我简单介绍一下第一种方式,着重介绍第二种。
第一种方式(Tomcat配置项配置允许或限制IP访问)
这种是最简单的快捷的,主要就涉及Tomcat的server.xml配置。
第一步:找到server.xml文件在哪,在Tomcat的目录下的conf文件夹下。
第二步:打开server.xml文件,找到Host节点,在其中加上:
allow="127.0.0.1"
deny=""/>
其中:
className:表示java类名,必须是
org.apache.catalina.valves.RemoteHostValve或org.apache.catalina.valves.RemoteAddrValve;
allow:表示允许的IP,支持模糊(* )、正则,多个用,隔开;
deny:表示限制的IP,支持模糊( *)、正则;多个用,隔开。
注:如果是限制某一个站点(网站)则在Context节点中添加。
第三步:重启Tomcat。
第二种方式(通过Filter过滤器来配置允许或限制IP访问)
(1)代码实现的思路
通过增加配置文件properties,将允许访问的IP按一定规则配置进去;接下来再对配置文件(这里尚且叫做配置文件)进行加载;然后再对配置文件的格式要求通过正则进行校验;其次将配置的IP通过一个集合进行收集,可收集单条IP或一个IP的正则,因为我们这里需要用到模糊;最后对访问者的IP与集合中的进行比对,比对通过则正常访问,否则。反之。
在配置文件中提供三种最常见的IP配置方式:
单个IP地址的配置,多个之间用逗号或分好隔开;
例如:192.168.1.50;127.0.0.1;IP地址区间方式的配置,多个区间用逗号或分好隔开;
例如:172.20.32.10-172.20.32.11;172.20.32.88-172.20.32.89通配符,多个用逗号或分好隔开。
例如:172.20.30.*
(2)具体实现代码
第一步:编写配置文件/Test/src/com/config/ipConfig.properties;
#单个IP地址的配置,多个之间用逗号或分好隔开
allowIP=192.168.1.50;127.0.0.1;
#IP地址区间方式的配置,多个区间用逗号或分好隔开
allowIPRange=172.20.32.10-172.20.32.11;172.20.32.88-172.20.32.89
#通配符,多个用逗号或分好隔开
allowIPWildcard=172.20.30.*;
第二步:新建Java类实现Filter;
第三步:在web.xml中配置过滤器;
IPFilter
com.filter.IpFilter
IPFilter
/*
第四步:我们需要声明一个全局变量List来存放允许访问的IP或正则式;
//声明的代码:
//用来存放允许访问的ip
private List allowList = new ArrayList();
第五步:需要对配置文件进行加载;在方法init中
//加载的代码:
//将文件转化成流
InputStream inputStream = IpFilter.class.getResourceAsStream("../config/ipConfig.properties");
Properties properties = new Properties();
//通过Properties对象实例加载流
properties.load(inputStream);
//获取三种配置方式的值
String allowIP = properties.getProperty("allowIP");
String allowIPRange = properties.getProperty("allowIPRange");
String allowIPWildcard = properties.getProperty("allowIPWildcard");
第六步:校验配置文件格式;在方法init中
//校验的部分代码
//如果为空,说明用户没添加该项,不做处理
if(allow == null || "".equals(allow.trim())) {
return true;
} else {
//在最后面没有,或;的给添上
if(!allow.endsWith(";") && !allow.endsWith(",")) {
allow += ";";
}
//如果匹配,则返回true
if(pattern.matcher(allow).matches()) {
return true;
}
}
第七步:获取每种配置方式的IP;在方法init中
/*
* 将每一种配置方法放置到allowList中
*/
//将第一种配置方法放到allowList中
if(null != allowIP && !"".equals(allowIP.trim())) {
String[] allowIPs = allowIP.split(",|;");
for(String ip : allowIPs) {
allowList.add(ip);
}
}
//将第二种配置方法放到allowList中
if(null != allowIPRange &&
!"".equals(allowIPRange.trim())) {
//先进行每一段的分割
String[] allowIPRanges = allowIPRange.split(",|;");
if(allowIPRanges.length > 0) {
//对每一段进行遍历
for(String allowRanges : allowIPRanges) {
if(allowRanges != null &&
!"".equals(allowRanges.trim())) {
//对该段的ip进行解析
String[] ips = allowRanges.split("-");
if(ips.length > 0 && ips.length < 3) {
String from = ips[0];//得到该段的起始ip
String to = ips[1]; //得到该段的结束ip
//获取该ip段地址的前三段,因为起始和结束的ip的前三段一样
String share = from.substring(0, from.lastIndexOf(".")+1);
//获取该ip段的起始ip的最后一段
int start = Integer.parseInt(from.substring(from.lastIndexOf(".")+1,
from.length()));
//获取该ip段的结束ip的最后一段
int end = Integer.parseInt(to.substring(to.lastIndexOf(".")+1,
to.length()));
for(int i=start; i<=end; i++) {
String ip = share + String.valueOf(i);
allowList.add(ip);
}
} else {
throw new RuntimeException("配置文件有错,请检查!");
}
}
}
}
}
//将第三种配置方法放到allowList中
if(allowIPWildcard != null &&
!"".equals(allowIPWildcard)) {
//获取每个含通配符的ip地址
String[] allowIPWildcards = allowIPWildcard.split(",|;");
if(allowIPWildcards.length > 0) {
for(String ip : allowIPWildcards) {
if(ip.indexOf("*") != -1) {
//对*进行替换
ip = ip.replaceAll("\\*", "(25[0-5]|2[0-4]\\\\d|[0-1]\\\\d{2}|[1-9]?\\\\d)");
allowList.add(ip);
} else {
throw new RuntimeException("配置文件有错,请检查!");
}
}
}
}
第八步:IP比对,成功匹配就正常访问,反之则跳到错误页面。这个因为是在用户访问时才进行的步骤,需要在doFilter方法的编写。
//获取访问的IP地址
String remoteAddr = request.getRemoteAddr();
//System.out.println("===============" + remoteAddr);
//如果allowList为空,则认为没做限制,不为空则检查是否限制
if(allowList.size() == 0 || allowList == null) {
filterChain.doFilter(request, response);
} else {
Boolean flag = false; //访问标志,默认为false,限制访问
//进行逐个检查
for(String regex : allowList){
if(remoteAddr.matches(regex)){
//ip没被限制,正常访问
filterChain.doFilter(request, response);
flag = true; //置为true,表示不限制访问
break;
}
}
if(!flag) {
//ip被限制,跳到指定页面
request.getRequestDispatcher("WEB-INF/success/error.jsp").forward(request, response);
}
}
附成功后截图:
附完整代码:
package com.filter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.regex.Pattern;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* 过滤器
* 功能:对访问者IP进行限制访问
* @author ouyang
* @serial 20180728
* @version 1.0
*/
public class IpFilter implements Filter{
//用来存放允许访问的ip
private List allowList = new ArrayList();
@Override
public void init(FilterConfig arg0) throws ServletException {
try {
System.out.println("过滤器IpFilter开始初始化,功能:IP访问限制");
initConfig();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws IOException, ServletException {
//获取访问的IP地址
String remoteAddr = request.getRemoteAddr();
//System.out.println("===============" + remoteAddr);
//如果allowList为空,则认为没做限制,不为空则检查是否限制
if(allowList.size() == 0 || allowList == null) {
filterChain.doFilter(request, response);
} else {
Boolean flag = false; //访问标志,默认为false,限制访问
//进行逐个检查
for(String regex : allowList){
if(remoteAddr.matches(regex)){
//ip没被限制,正常访问
filterChain.doFilter(request, response);
flag = true; //置为true,表示不限制访问
break;
}
}
if(!flag) {
//ip被限制,跳到指定页面
request.getRequestDispatcher("WEB-INF/success/error.jsp").forward(request, response);
}
}
}
@Override
public void destroy() {
System.out.println("过滤器IpFilter结束。");
}
/**
* 对配置文件进行初始化并校验
* @author 欧阳
* @serialData 20180728
* @throws IOException
*/
public void initConfig() throws IOException {
//将文件转化成流
InputStream inputStream = IpFilter.class.getResourceAsStream("../config/ipConfig.properties");
Properties properties = new Properties();
//通过Properties对象实例加载流
properties.load(inputStream);
//获取三种配置方式的值
String allowIP = properties.getProperty("allowIP");
String allowIPRange = properties.getProperty("allowIPRange");
String allowIPWildcard = properties.getProperty("allowIPWildcard");
//校验,校验失败后抛出异常
if(!validate(allowIP, allowIPRange, allowIPWildcard)) {
throw new RuntimeException("配置文件有错,请检查!");
}
/*
* 将每一种配置方法放置到allowList中
*/
//将第一种配置方法放到allowList中
if(null != allowIP && !"".equals(allowIP.trim())) {
String[] allowIPs = allowIP.split(",|;");
for(String ip : allowIPs) {
allowList.add(ip);
}
}
//将第二种配置方法放到allowList中
if(null != allowIPRange &&
!"".equals(allowIPRange.trim())) {
//先进行每一段的分割
String[] allowIPRanges = allowIPRange.split(",|;");
if(allowIPRanges.length > 0) {
//对每一段进行遍历
for(String allowRanges : allowIPRanges) {
if(allowRanges != null &&
!"".equals(allowRanges.trim())) {
//对该段的ip进行解析
String[] ips = allowRanges.split("-");
if(ips.length > 0 && ips.length < 3) {
String from = ips[0];//得到该段的起始ip
String to = ips[1]; //得到该段的结束ip
//获取该ip段地址的前三段,因为起始和结束的ip的前三段一样
String share = from.substring(0, from.lastIndexOf(".")+1);
//获取该ip段的起始ip的最后一段
int start = Integer.parseInt(from.substring(from.lastIndexOf(".")+1,
from.length()));
//获取该ip段的结束ip的最后一段
int end = Integer.parseInt(to.substring(to.lastIndexOf(".")+1,
to.length()));
for(int i=start; i<=end; i++) {
String ip = share + String.valueOf(i);
allowList.add(ip);
}
} else {
throw new RuntimeException("配置文件有错,请检查!");
}
}
}
}
}
//将第三种配置方法放到allowList中
if(allowIPWildcard != null &&
!"".equals(allowIPWildcard)) {
//获取每个含通配符的ip地址
String[] allowIPWildcards = allowIPWildcard.split(",|;");
if(allowIPWildcards.length > 0) {
for(String ip : allowIPWildcards) {
if(ip.indexOf("*") != -1) {
//对*进行替换
ip = ip.replaceAll("\\*", "(25[0-5]|2[0-4]\\\\d|[0-1]\\\\d{2}|[1-9]?\\\\d)");
allowList.add(ip);
} else {
throw new RuntimeException("配置文件有错,请检查!");
}
}
}
}
//打印输出allowList
for(String str : allowList) {
System.out.println(str);
}
}
/**
* 对配置文件进行校验
* @author ouyang
* @serialData 20180728
* @param allowIP
* @param allowIPRange
* @param allowIPWildcard
* @return
*/
public Boolean validate(String allowIP, String allowIPRange, String allowIPWildcard) {
Boolean result = false;
//IP地址每一段的正则
String regx = "(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)";
//整个ip的正则
String ipRegx = regx + "\\." + regx + "\\."+ regx + "\\." + regx;
//对第一种方式进行校验
Pattern pattern = Pattern.compile("("+ipRegx+")|("+ipRegx+"(,|;))*");
if(this.isNullorMatches(allowIP, pattern)){
result = true; //匹配成功
} else {
result = false;
}
//对第二种方式进行校验
pattern = Pattern.compile("("+ipRegx+")\\-("+ipRegx+")|" +
"(("+ipRegx+")\\-("+ipRegx+")(,|;))*");
if(this.isNullorMatches(allowIPRange, pattern)){
result = true; //匹配成功
} else {
result = false;
}
//对第三种方式进行校验
pattern = Pattern.compile("("+regx+"\\."+ regx+"\\."+regx+"\\."+ "\\*)|" +
"("+regx+"\\."+regx+"\\."+regx+"\\."+ "\\*(,|;))*");
if(this.isNullorMatches(allowIPWildcard, pattern)){
result = true; //匹配成功
} else {
result = false;
}
return result;
}
/**
* 进行正则匹配
* @author 欧阳
* @serialData 20180728
* @param allow
* @return
*/
public Boolean isNullorMatches(String allow, Pattern pattern) {
//如果为空,说明用户没添加该项,不做处理
if(allow == null || "".equals(allow.trim())) {
return true;
} else {
//在最后面没有,或;的给添上
if(!allow.endsWith(";") && !allow.endsWith(",")) {
allow += ";";
}
//如果匹配,则返回true
if(pattern.matcher(allow).matches()) {
return true;
}
}
return false;
}
}
到此这篇关于详解Java Web如何限制访问的IP的两种方法的文章就介绍到这了,更多相关Java 限制访问的IP内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
java web ip_详解Java Web如何限制访问的IP的两种方法相关推荐
- 【XCTF 攻防世界 web 练习详解系列(二)】【get_post的两种解法】
目录 get_post 题目链接 题目描述 知识点 HTTP中GET.POST用法以及它们的区别 工具的使用 题解 方法1 方法2 get_post 题目链接 题目描述 X老师告诉小宁同学HTTP通常 ...
- 《 Python List列表全实例详解系列(三)》——列表添加元素(4种方法)
< Python List列表全实例详解系列(三)> --列表添加元素(4种方法) 接上一篇:< Python List 列表全实例详解(二)>__访问列表元素(索引和切片)列 ...
- 详解易语言调用大漠插件注册vip的三种方法
详解易语言调用大漠插件注册vip的三种方法 1.将大漠插件所有命令封装成易语言类模块.(类模块调用法) 2.将大漠插件所有命令封装成Ec模块(EC模块调用法) 3.将大漠插件所有命令封装成易语言支持库 ...
- java lock unlock_详解Java中的ReentrantLock锁
ReentrantLock锁 ReentrantLock是Java中常用的锁,属于乐观锁类型,多线程并发情况下.能保证共享数据安全性,线程间有序性 ReentrantLock通过原子操作和阻塞实现锁原 ...
- java system sleep_详解Java中的sleep()和wait()的区别
详解Java中的sleep()和wait()的区别 对于sleep()方法,我们首先要知道该方法是属于Thread类中的.而wait()方法,则是属于Object类中的. sleep()方法导致了程序 ...
- java中priorityqueue_详解JAVA中priorityqueue的具体使用
Java中PriorityQueue通过二叉小顶堆实现,可以用一棵完全二叉树表示.本文从Queue接口函数出发,结合生动的图解,深入浅出地分析PriorityQueue每个操作的具体过程和时间复杂度, ...
- java中implement_详解JAVA中implement和extends的区别
详解JAVA中implement和extends的区别 extends是继承父类,只要那个类不是声明为final或者那个类定义为abstract的就能继承,Java中不支持多重继承,但是可以用接口来实 ...
- java中getclass_详解java中this.getClass()和super.getClass()的实例
详解java中this.getClass()和super.getClass()的实例 前言: 遇到this.getClass()和super.getClass()的返回值感到疑惑,经过探索豁然开朗. ...
- java 重定向 redirect_详解Java从后台重定向(redirect)到另一个项目的方法
(1)通过ModelAndView跳转 @RequestMapping("alipayforward") public ModelAndView alipayforward(Htt ...
最新文章
- 《统一沟通-微软-技巧》-20-Lync 2010如何在我的联系人列表中添加非联盟联系人...
- 发光二极管pcb封装图画法_五个方面剖析SIP封装工艺,看懂SIP封装真正用途
- 推荐系统--基于用户的协同过滤算法
- SeqStack(Templateclass T)实现
- Android 双击和手势的图片缩放
- com 组件调用不起来_一文读懂Eureka,Feign,Ribbon,Hystrix,Zuul核心组件间的关系...
- 虚拟机ubuntu19.04下设置idea快捷键
- spring通用获取ioc容器中配置的bean的工具类
- NodeJS对mysql数据库的简单操作
- sqlserver tvps java_中毒了,请高手看一下诊断报告。
- 【超全面】Python内置函数详解
- 基于宏指令下的威纶通配方功能(RW位控制)
- 并网逆变器的clark、park变换的C语言实现技巧
- 良仓远行 · 硅谷遇上西雅图,同游招募
- 知识蒸馏与半监督学习
- Linux的企鹅图标
- 宽度优先搜索(BFS)
- 【Linux进程】Linux进程
- 微信小程序开发(一)系统对接微信UGC类小程序内容安全接口JAVA版
- 全球十大最受欢迎的猫咪品种排行榜公布,布偶猫连续三年排名第一
热门文章
- springboot集成phoenix,操作hbase
- 2020美国纽约大学计算机科学排名,2020年美国纽约大学专业排名
- Perseus(擎天):统一深度学习分布式通信框架
- [c++]c++程序设计-Y.Daniel.Liang 笔记
- Apache ShenYu ModifyResponse插件使用
- JQ---h5页面上实现微信扫一扫功能
- 基于Java毕业设计弹幕视频网站源码+系统+mysql+lw文档+部署软件
- Android高德地图基本开发/在线高德离线地图开发/断网使用离线地图(Assets文件夹的使用)
- 金蝶EAS,序时簿界面ListUI数据不允许修改、删除
- grep查找的内容输出到文件