时间:2021-05-19
前一阵子因为在做项目时碰到了这个功能,现在好好总结一下,至于为什么要限制IP访问,我就不多说了。然后百度了一下,现在主要有两种方式去限制IP访问,第一种是最简单的方便的,第二种是通过过滤器来限制访问。下面我简单介绍一下第一种方式,着重介绍第二种。
第一种方式(Tomcat配置项配置允许或限制IP访问)
这种是最简单的快捷的,主要就涉及Tomcat的server.xml配置。
第一步:找到server.xml文件在哪,在Tomcat的目录下的conf文件夹下。
第二步:打开server.xml文件,找到Host节点,在其中加上:
其中:
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;
第二步:新建Java类实现Filter;
第三步:在web.xml中配置过滤器;
第四步:我们需要声明一个全局变量List来存放允许访问的IP或正则式;
//声明的代码://用来存放允许访问的ipprivate List<String> allowList = new ArrayList<String>();第五步:需要对配置文件进行加载;在方法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<String> allowList = new ArrayList<String>(); @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内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
什么是Nginx访问限制配置nginx访问限制可以基于两个方面,一个是基于ip的访问控制,另一个是基于用户的信任登陆控制下面我们将对这两种方法逐个介绍基于IP的
java深拷贝与浅拷贝机制详解概要:在Java中,拷贝分为深拷贝和浅拷贝两种。java在公共超类Object中实现了一种叫做clone的方法,这种方法clone
前言在java中遍历Map有不少的方法。这篇文章我们就来看一下Java读取Map的两种方法以及这两种方法的对比。一、遍历Map方法AMapmap=newHash
对于限制了ip和来源的网站,使用正常的访问方式是无法访问的。本文将介绍一种方法,使用php的curl类实现模拟ip和来源,访问那些限制了ip和来源的网站。1.设
如何在Mac上卸载Java?下面小编给大家带来如何在Mac上卸载已经安装了的java的详细教程,主要由以下两种方法:软件名称:JavaSERuntimeEnvi