很久没有写技术文档了,今天 记录下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限制了
CXF 的IP拦截
时间: 2024-10-10 17:26:30