1. 程式人生 > >cxf中自定義攔截器限制IP

cxf中自定義攔截器限制IP

import java.util.List;  
  
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;  
  
/** 
 * IP地址攔截器 
 * 可在filter.xml檔案中配置允許和拒絕訪問的IP地址 
 * @author Sunshine 
 * 
 */  
public class IpAddressInInterceptor extends AbstractPhaseInterceptor<Message> {  
  
    public IpAddressInInterceptor() {  
        super(Phase.RECEIVE);  
    }  
  
    public void handleMessage(Message message) throws Fault {  
        HttpServletRequest request = (HttpServletRequest) message.get(AbstractHTTPDestination.HTTP_REQUEST);  
        // 通過一個IpAddressConfig物件,從XML檔案中讀取預先設定的允許和拒絕的IP地址,這些值也可以來自資料庫  
        IpAddressConfig config = IpAddressConfig.getInstance(); // 獲取config例項  
        List<String> allowedList = config.getAllowedList(); // 允許訪問的IP地址  
        List<String> deniedList = config.getDeniedList(); // 拒絕訪問的IP地址  
        String ipAddress = request.getRemoteAddr(); // 取客戶端IP地址  
        // 先處理拒絕訪問的地址  
        for (String deniedIpAddress : deniedList) {  
            if (deniedIpAddress.equals(ipAddress)) {  
                throw new Fault(new IllegalAccessException("IP address " + ipAddress + " is denied"));  
            }  
        }  
        // 如果允許訪問的集合非空,繼續處理,否則認為全部IP地址均合法  
        if (allowedList.size() > 0) {  
            boolean contains = false;  
            for (String allowedIpAddress : allowedList) {  
                if (allowedIpAddress.equals(ipAddress)) {  
                    contains = true;  
                    break;  
                }  
            }  
            if (!contains) {  
                throw new Fault(new IllegalAccessException("IP address " + ipAddress + " is not allowed"));  
            }  
        }  
    }  
  
}  

IP地址允許和阻止列表來自一個自定義的filter.xml檔案,這個值也可以來自資料庫。當顯式丟擲Fault異常的時候,這個請求即被阻止,否則放行。  在applicationContext-cxf.xml中要相應的定義這個IP地址攔截器,使之生效。 

<!-- IP地址輸入攔截器 -->  
<bean id="ipAddressInInterceptor"  
    class="com.yourcompany.ws.interceptor.IpAddressInInterceptor" />  
  
<!-- 使用者名稱和密碼輸入攔截器 -->  
<bean id="wss4jInInterceptor"  
    class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">  
    <property name="properties">  
        <map>  
            <entry key="action" value="UsernameToken Timestamp" />  
            <entry key="passwordType" value="PasswordDigest" />  
            <entry key="passwordCallbackRef"  
                value-ref="digestPasswordCallback" />  
        </map>  
    </property>  
</bean>  
  
<!-- 密碼回撥 -->  
<bean id="digestPasswordCallback"  
    class="com.yourcompany.ws.handler.DigestPasswordCallback" />  
  
<!-- 全域性Bus(輸入攔截器) -->  
<cxf:bus>  
    <cxf:inInterceptors>  
        <ref bean="ipAddressInInterceptor" />  
        <ref bean="wss4jInInterceptor" />  
    </cxf:inInterceptors>  
</cxf:bus>  
  
<!-- WebService服務 -->  
<jaxws:endpoint id="helloWorldServiceEP" address="/HelloWorldService">  
    <jaxws:implementor ref="helloWorldService" />  
</jaxws:endpoint>  
<bean id="helloWorldService"  
    class="com.yourcompany.ws.impl.HelloWorldServiceImpl" />