cxf+spring开发(二)--- Ip地址拦截器,限制客户端Ip地址,只允许数据库中已经配置的Ip地址

上上篇博文中介绍了如何搭建cxf和spring环境,本文将围绕如何在此环境下编写拦截器,只允许已经配置好的IP地址访问服务器端。

一、修改配置文件applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
    xmlns:p="http://www.springframework.org/schema/p"  
    xmlns:jaxws="http://cxf.apache.org/jaxws"   
    xmlns:cxf="http://cxf.apache.org/core"  
    xmlns:http-conf="http://cxf.apache.org/transports/http/configuration"
    xsi:schemaLocation="http://www.springframework.org/schema/beans   
    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd   
    http://cxf.apache.org/jaxws   
    http://cxf.apache.org/schemas/jaxws.xsd
    http://cxf.apache.org/transports/http/configuration
    http://cxf.apache.org/schemas/configuration/http-conf.xsd 
    http://cxf.apache.org/core 
    http://cxf.apache.org/schemas/core.xsd">  
      
    <import resource="classpath:META-INF/cxf/cxf.xml" />  
    <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />  
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />  
    
    <!-- WebService服务 --> 
    <bean id="inter" class="com.yolanda.cxfTest.AImpl"/>  

    <jaxws:endpoint id="cxfService" implementor="#inter" address="/CxfService" >
          <jaxws:inInterceptors>
            <ref bean="ipInIntercept"/>
        </jaxws:inInterceptors>
    </jaxws:endpoint>

    <!--毫秒单位 name 为 webservice 的域名 或者地址-->
    <http-conf:conduit name="${train.api.domain.name}.*">
        <http-conf:client ConnectionTimeout="10000" ReceiveTimeout="20000"/>
    </http-conf:conduit>

    <bean id="logIn" class="org.apache.cxf.interceptor.LoggingInInterceptor"/>
    <bean id="logOut" class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
    
     <!-- 自定义拦截器-->
    <bean id="ipInIntercept" class="com.intercept.IpInIntercept"/>
  

    <!-- CXF 全局的拦截器-->
   <cxf:bus>
       <cxf:inInterceptors>
           <ref bean="logIn"/>
       </cxf:inInterceptors>
       <cxf:outInterceptors>
           <ref bean="logOut" />
       </cxf:outInterceptors>
   </cxf:bus>

    
</beans> 


在这个地方遇到一个标签错误,错误提示

 

 

cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'jaxws:inInterceptors'.参见我的另一篇博文http://blog.csdn.net/yolanda_nuonuo/article/details/47016981

 

 

二、web.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>cxfTest</display-name>
 
   <context-param>  
        <param-name>contextConfigLocation</param-name>  
        <param-value>classpath:applicationContext.xml</param-value>  
    </context-param>
    
     <listener>  
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
    </listener>
    
    <listener>  
                  <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>  
    </listener>
    
    <!-- WebServices设置 -->
    <servlet>  
        <servlet-name>CxfService</servlet-name>  
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>  
        <load-on-startup>1</load-on-startup>  
    </servlet>  
      
    <servlet-mapping>  
        <servlet-name>CxfService</servlet-name>  
        <url-pattern>/*</url-pattern>  
    </servlet-mapping>  
 
    <welcome-file-list>  
        <welcome-file>index.jsp</welcome-file>  
    </welcome-file-list>
    
</web-app>

​


三、拦截器的编写

​import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

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;


/**
 * Ip拦截器
 *
 */
public class IpInIntercept extends AbstractPhaseInterceptor<Message>{

    private List<String> ipList = new ArrayList<String>();
    
    private final static Logger logger = LoggerFactory.getLogger(IpInIntercept.class);
    
    public IpInIntercept() {
        super(Phase.RECEIVE);
    }

    public void handleMessage(Message message) throws Fault {
        HttpServletRequest request = (HttpServletRequest) message.get(AbstractHTTPDestination.HTTP_REQUEST);
        String ipAddress = "";
        
        ConnOracle co = new ConnOracle();
        co.getConn();
        String sql = "select * from IPADDR";
        co.sqlExe(sql);
        
        boolean flag = false;
        int count = 0;
        
        if (null != request && count <= 10) {
            ipAddress = getUsrIPAddr(request);//获取客户端的IP地址
            logger.info("获取到客户端的IP地址是:" + ipAddress);
            System.out.println("获取到客户端的IP地址是:" + ipAddress);
            count++;
            
            for (String ipString : ipList) {
                if (ipString.equals(ipAddress)) {
                    flag = true;
                    break;
                }
            }
        }
        
        if (!flag) {  
            throw new Fault(new IllegalAccessException("IP address " + ipAddress + " is not allowed"));  
        }
        
    }
    
    /**
     * 获取客户端ip地址  
     * @param request
     * @return
     */
    public String getUsrIPAddr(HttpServletRequest request) {
        String ip = "";
        //1.首先考虑有反向代理的情况,如果有代理,通过“x-forwarded-for”获取真实ip地址
        ip = request.getHeader("x-forwarded-for");
        //2.如果squid.conf的配制文件forwarded_for项默认是off,则:X-Forwarded-For:unknown。考虑用Proxy-Client-IP或WL-Proxy-Client-IP获取
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        //3.最后考虑没有代理的情况,直接用request.getRemoteAddr()获取ip
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        //4.如果通过多级反向代理,则可能产生多个ip,其中第一个非unknown的IP为客户端真实IP(IP按照','分割)
        if(ip != null && ip.split(",").length > 1){
            ip = (ip.split(","))[0];
        }        
        //5.如果是服务器本地访问,需要根据网卡获取本机真实ip
        if("127.0.0.1".equals(ip)) {
            try {
                ip = InetAddress.getLocalHost().getHostAddress();
            } catch (UnknownHostException e) {
                logger.error(e.getMessage(),e);//获取服务器(本地)ip信息失败
                return "";
            }
        }
//        6.校验ip的合法性,不合法返回""
        if(!isValidIp(ip)) {
            return "The ip is invalid.";
        }else {
            return ip;
        }
//        return ip;
    }

    /**
     * 判断是否为合法IP地址
     * @param ipAddress
     * @return
     */
    private boolean isValidIp(String ipAddress) {
        boolean retVal = false;
        try {
            if(ipAddress!=null && !"".equals(ipAddress)){
                Pattern pattern = Pattern.compile("([1-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}");
                retVal = pattern.matcher(ipAddress).matches();
            }            
        } catch(Exception e){
            logger.error(e.getMessage(), e);
        }
        return retVal;
    }

}

​

 

三、数据库工具类

由于使用了oracle数据库,所以还要编写数据库工具类如下。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * 数据库连接
 *
 */
public class ConnOracle {
	//数据库连接驱动
	public static final String driver = "oracle.jdbc.driver.OracleDriver";
	//数据库连接地址
	public static final String url = "jdbc:oracle:thin:@172.25.2.148:1521:ORCL";
	//登录名
	public static final String usr = "twj";
	//密码
	public static final String pwd = "123";
	//数据库连接对象
	private Connection conn = null;
	//数据库预编译对象
	private PreparedStatement ps = null;
	//结果集
	private ResultSet rs = null;
	//结果字符串
	private List<String> list = new ArrayList<String>();
	
	/**
	 * 获取数据库连接
	 * @return conn
	 */
	public Connection getConn() {
		try {
			Class.forName(driver);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		try {
			conn = DriverManager.getConnection(url, usr, pwd);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return conn;
	}
	
	/**
	 * 关闭所有资源
	 */
	public void closeAll()
	{
		if (ps != null) {
			try {
				ps.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		
		if (conn != null) {
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}//if
		
	}
	
	/**
	 * 执行sql语句
	 * @param sqlString
	 */
	public List<String> sqlExe(String sqlString)
	{
		try {
			ps = conn.prepareStatement(sqlString);
			rs = ps.executeQuery();
			while (rs.next()) {
				list.add(rs.getString(2));
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return list;
	}

}


​

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值