很久沒有寫技術文檔了,今天 記錄下Webserver的Ip限制吧
需求是:webserver接口能在內網訪問,但是測試平臺的webserver要可以在外網訪問,這樣就有了一點區別,
這個實現的比較簡單配置文件就一個白名單
#可用的IP
whiteList=a;b;
表示一個內網網段都可以訪問
用配置文件讀取
package com.onepiece.cxf.util;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.ResourceBundle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 配置文件工具
*
* @author JueYue
* @date 2014年7月3日 下午5:06:35
*/
public class CxfInterceptorProperties {
private static final Logger logger = LoggerFactory
.getLogger(CxfInterceptorProperties.class);
private static boolean isNotIntercept = false;
private static List<String> whiteList;
static {
ResourceBundle bundle;
try {
bundle = ResourceBundle.getBundle("cxf-interceptor");
} catch (Exception e) {
logger.info("cxf-interceptor沒有配置配置文件,使用缺省配置");
bundle = ResourceBundle
.getBundle("com/onepiece/cxf/util/cxf-interceptor");
}
whiteList = Arrays.asList(bundle.getString("whiteList").split(";"));
try {
Enumeration<NetworkInterface> netInterfaces = NetworkInterface
.getNetworkInterfaces();
String ip;
while (netInterfaces.hasMoreElements()) {
NetworkInterface nif = netInterfaces.nextElement();
Enumeration<InetAddress> iparray = nif.getInetAddresses();
while (iparray.hasMoreElements()) {
ip = iparray.nextElement().getHostAddress();
if (ip.contains("192.168.0")) {
logger.info("發現測試IP地址,取消IP限制");
isNotIntercept = true;
break;
}
logger.debug("本機IP爲:{}",ip);
}
}
} catch (Exception e) {
logger.info("獲取IP失敗,默認啓用攔截");
e.printStackTrace();
}
}
public static List<String> getWhiteList() {
return whiteList;
}
public static boolean isNotIntercept() {
return isNotIntercept;
}
}
自己設置一個默認配置,但是測試平臺的話就沒有IP限制了,這裏獲取IP地址複雜點,因爲可能存在多個IP所以都獲取發現一下自己想要的IP地址
然後是IP攔截
package com.onepiece.cxf.address;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.apache.cxf.transport.http.AbstractHTTPDestination;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.onepiece.cxf.util.CxfInterceptorProperties;
/**
* 攔截配置文件的配置
*
* @author JueYue
* @date 2014年7月3日 下午5:05:46
*/
public class IpAddressInInterceptor extends AbstractPhaseInterceptor<Message> {
private static final Logger logger = LoggerFactory
.getLogger(IpAddressInInterceptor.class);
public IpAddressInInterceptor() {
super(Phase.RECEIVE);
}
public void handleMessage(Message message) throws Fault {
HttpServletRequest request = (HttpServletRequest) message
.get(AbstractHTTPDestination.HTTP_REQUEST);
List<String> allowedList = CxfInterceptorProperties.getWhiteList();
if (logger.isDebugEnabled() && request != null) {
logger.debug("getRemoteAddr 獲取的IP:{},X-Client-Address 獲取的IP:{}",
request.getRemoteAddr(),request.getHeader("X-Client-Address"));
}
if (CxfInterceptorProperties.isNotIntercept() || request == null) {
return;
}
String ipAddress = getIP(request);
// 處理白名單
boolean contains = false;
for (String allowIpAddress : allowedList) {
if (ipAddress.startsWith(allowIpAddress)) {
contains = true;
break;
}
}
if (!contains) {
logger.warn("***********************發現一個外來IP,IP地址:" + ipAddress
+ "**************");
throw new Fault(new IllegalAccessException("IP address "
+ ipAddress + " is not allowed"));
}
}
private String getIP(HttpServletRequest request) {
String IP = request.getHeader("X-Client-Address"); // 取客戶端IP地址
if (StringUtils.isEmpty(IP)) {
IP = request.getRemoteAddr();
}
return IP;
}
}
這裏獲取IP首先是X-Clint-Address 因爲我們是用的PortTunnel代理的,這個設置下就可以在X-cliet-Address獲取真實IP
這樣我們就做到了IP限制.後面就是配置下
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:cxf="http://cxf.apache.org/core"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd"
default-autowire="byName">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<!-- IP地址輸入攔截器 -->
<bean id="ipAddressInInterceptor"
class="com.onepiece.cxf.address.IpAddressInInterceptor" />
<!-- 全局Bus(輸入攔截器) -->
<cxf:bus>
<cxf:inInterceptors>
<ref bean="ipAddressInInterceptor"/>
</cxf:inInterceptors>
</cxf:bus>
</beans>
使用的是全局設置,所以不用每個都配置,這裏需要注意一點default-lazy-init="true" 如果spring加上這個就會失效,
這裏基本就完成了IP限制了