有些项目的接口是需要权限访问,比如限制IP、做权限控制,等等方案,本文是限制ip权限设置访问策略。
先看测试效果:
测试:
注意访问需要输入:http://127.0.0.1:8981/
在配置文件加上本地的ip 10.9.160.135
去掉本地ip 10.9.160.135 提示非法字符
看一下项目结构,新建一个创建IPLimitInterceptor类,在springmvc配置文件配置、新建一个ip校验工具类 IPWhiteListUtil、ip配置文件: ipwhite.properties。
再看代码实现
创建IPLimitInterceptor类
PLimitInterceptor继承HandlerInterceptorAdapter父类
import java.net.InetAddress;
import java.util.Properties;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
public class IPLimitInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {undefined
String ip = getIpAddress(request);
//读取ip白名单配置文件ipwhite.properties
Properties properties = PropertiesLoaderUtils.loadAllProperties("ipwhite.properties");
String ipWhilte = properties.getProperty("ipWhilte");
System.out.println(ipWhilte);
//判断请求ip地址 是否在白名单呢
if(IPWhiteListUtil.checkLoginIP(ip,ipWhilte)) {undefined
return super.preHandle(request, response, handler);
}
throw new Exception("IP非法访问!");
}
//获取配置请求的ip地址
private String getIpAddress(HttpServletRequest request) {undefined
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {undefined
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {undefined
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {undefined
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {undefined
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {undefined
ip = request.getRemoteAddr();
System.out.println("访问ip="+ip);
if(ip.equals("127.0.0.1")){
//根据网卡取本机配置的IP
InetAddress inet=null;
try {
inet = InetAddress.getLocalHost();
} catch (Exception e) {
e.printStackTrace();
}
ip= inet.getHostAddress();
}
}
//对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
if(ip!=null && ip.length()>15){ //"***.***.***.***".length() = 15
if(ip.indexOf(",")>0){
ip = ip.substring(0,ip.indexOf(","));
}
}
System.out.println("访问ip========="+ip);
return ip;
}
}
在springmvc配置文件配置:
<mvc:interceptors>
<!-- IP鉴权拦截器 -->
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.*.*.ipwhite.IPLimitInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
再新建一个ip校验类 IPWhiteListUtil
/**
* IP校验类的方法
*/
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
public class IPWhiteListUtil {
// IP的正则
private static Pattern pattern = Pattern
.compile("(1\\d{1,2}|2[0-4]\\d|25[0-5]|\\d{1,2})\\."
+ "(1\\d{1,2}|2[0-4]\\d|25[0-5]|\\d{1,2})\\."
+ "(1\\d{1,2}|2[0-4]\\d|25[0-5]|\\d{1,2})\\."
+ "(1\\d{1,2}|2[0-4]\\d|25[0-5]|\\d{1,2})");
/**
*
* getAvaliIpList:(根据IP白名单设置获取可用的IP列表).
* @return
*/
private static Set getAvaliIpList(String allowIp) {
Set<String> ipList = new HashSet();
for (String allow : allowIp.replaceAll("\\s", "").split(";")) {
if (allow.indexOf("*") > -1) {
String[] ips = allow.split("\\.");
String[] from = new String[] { "0", "0", "0", "0" };
String[] end = new String[] { "255", "255", "255", "255" };
List<String> tem = new ArrayList();
for (int i = 0; i < ips.length; i++)
if (ips[i].indexOf("*") > -1) {
tem = complete(ips[i]);
from[i] = null;
end[i] = null;
} else {
from[i] = ips[i];
end[i] = ips[i];
}
StringBuffer fromIP = new StringBuffer();
StringBuffer endIP = new StringBuffer();
for (int i = 0; i < 4; i++){
if (from[i] != null) {
fromIP.append(from[i]).append(".");
endIP.append(end[i]).append(".");
} else {
fromIP.append("[*].");
endIP.append("[*].");
}
}
fromIP.deleteCharAt(fromIP.length() - 1);
endIP.deleteCharAt(endIP.length() - 1);
for (String s : tem) {
String ip = fromIP.toString().replace("[*]",
s.split(";")[0])
+ "-"
+ endIP.toString().replace("[*]", s.split(";")[1]);
if (validate(ip)) {
ipList.add(ip);
}
}
} else {
if (validate(allow)) {
ipList.add(allow);
}
}
}
return ipList;
}
private static Set getAvaliIpList(Set<String> ipSet) {
Set<String> ipList = new HashSet();
for (String allow : ipSet) {
if (allow.indexOf("*") > -1) {
String[] ips = allow.split("\\.");
String[] from = new String[] { "0", "0", "0", "0" };
String[] end = new String[] { "255", "255", "255", "255" };
List<String> tem = new ArrayList();
for (int i = 0; i < ips.length; i++)
if (ips[i].indexOf("*") > -1) {
tem = complete(ips[i]);
from[i] = null;
end[i] = null;
} else {
from[i] = ips[i];
end[i] = ips[i];
}
StringBuffer fromIP = new StringBuffer();
StringBuffer endIP = new StringBuffer();
for (int i = 0; i < 4; i++) {
if (from[i] != null) {
fromIP.append(from[i]).append(".");
endIP.append(end[i]).append(".");
} else {
fromIP.append("[*].");
endIP.append("[*].");
}
}
fromIP.deleteCharAt(fromIP.length() - 1);
endIP.deleteCharAt(endIP.length() - 1);
for (String s : tem) {
String ip = fromIP.toString().replace("[*]",
s.split(";")[0])
+ "-"
+ endIP.toString().replace("[*]", s.split(";")[1]);
if (validate(ip)) {
ipList.add(ip);
}
}
} else {
if (validate(allow)) {
ipList.add(allow);
}
}
}
return ipList;
}
/**
* 对单个IP节点进行范围限定
*
* @param arg
* @return 返回限定后的IP范围,格式为List[10;19, 100;199]
*/
private static List complete(String arg) {
List com = new ArrayList();
if (arg.length() == 1) {
com.add("0;255");
} else if (arg.length() == 2) {
String s1 = complete(arg, 1);
if (s1 != null){
com.add(s1);
}
String s2 = complete(arg, 2);
if (s2 != null){
com.add(s2);
}
} else {
String s1 = complete(arg, 1);
if (s1 != null){
com.add(s1);
}
}
return com;
}
private static String complete(String arg, int length) {
String from = "";
String end = "";
if (length == 1) {
from = arg.replace("*", "0");
end = arg.replace("*", "9");
} else {
from = arg.replace("*", "00");
end = arg.replace("*", "99");
}
if (Integer.valueOf(from) > 255){
return null;
}
if (Integer.valueOf(end) > 255){
end = "255";
}
return from + ";" + end;
}
/**
* 在添加至白名单时进行格式校验
*
* @param ip
* @return
*/
private static boolean validate(String ip) {
for (String s : ip.split("-")){
if (!pattern.matcher(s).matches()) {
return false;
}
}
return true;
}
/**
*
* checkLoginIP:(根据IP,及可用Ip列表来判断ip是否包含在白名单之中).
* @param ip
* @param ipList
* @return
*/
private static boolean checkLoginIP(String ip, Set<String> ipList) {
if (ipList.contains(ip)){
return true;
}else {
for (String allow : ipList) {
if (allow.indexOf("-") > -1) {
String[] from = allow.split("-")[0].split("\\.");
String[] end = allow.split("-")[1].split("\\.");
String[] tag = ip.split("\\.");
// 对IP从左到右进行逐段匹配
boolean check = true;
for (int i = 0; i < 4; i++) {
int s = Integer.valueOf(from[i]);
int t = Integer.valueOf(tag[i]);
int e = Integer.valueOf(end[i]);
if (!(s <= t && t <= e)) {
check = false;
break;
}
}
if (check) {
return true;
}
}
}
}
return false;
}
/**
*
* checkLoginIP:(根据IP地址,及IP白名单设置规则判断IP是否包含在白名单).
* @param ip
* @param ipWhiteConfig
* @return
*/
public static boolean checkLoginIP(String ip,String ipWhiteConfig){
Set ipList = getAvaliIpList(ipWhiteConfig);
return checkLoginIP(ip, ipList);
}
/**
*
* ip在ipList中,则返回true
* @param ip
* @param ipList
* @return
*/
public static boolean checkIpList(String ip,List<String> ipList){
Set<String> ipSet = new HashSet();
for(String ipStr : ipList){
if(!ipStr.trim().startsWith("#")){
ipSet.add(ipStr.trim());
}
}
ipSet = getAvaliIpList(ipSet);
return checkLoginIP(ip, ipSet);
}
// 测试
public static void main(String[] args) {
String ipWhilte = "192.168.1.1;" + //设置单个IP的白名单
"192.168.2.*;" + //设置ip通配符,对一个ip段进行匹配
"192.168.3.17-192.168.3.38"; //设置一个IP范围
System.out.println(ipWhilte);
boolean flag = checkLoginIP("192.168.2.2",ipWhilte);
boolean flag2 = checkLoginIP("192.168.1.2",ipWhilte);
boolean flag3 = checkLoginIP("192.168.3.16",ipWhilte);
boolean flag4 = checkLoginIP("192.168.3.17",ipWhilte);
System.out.println(flag); //true
System.out.println(flag2); //false
System.out.println(flag3); //false
System.out.println(flag4); //true
}
}
#配置白名单-可改成数据库获取或配置文件配置
#//设置单个IP的白名单 “192.168.1.1;”
#//设置ip通配符,对一个ip段进行匹配 “192.168.2.*;”
#//设置一个IP范围 “192.168.12.17-192.168.12.150”
ipWhilte = 192.168.1.1;192.168.2.*;192.168.2.17-192.168.12.150;10.9.160.135;
测试:
注意访问需要输入:http://127.0.0.1:8981/hello
在配置文件加上本地的ip 10.9.160.135
去掉本地ip 10.9.160.135 提示非法字符