CXF 入門:建立一個基於SOAPHeader的安全驗證(CXF攔截器使用)

下面具體的webservice實現類直接用的是上面的,這裏再也不說明 java

CXF攔截器使用,建立一個使用SOAPHeader的安全驗證  
xml格式:  
web

<soap:Header>  
    <auth:authentication xmlns:auth="http://gd.chinamobile.com//authentication">  
        <auth:systemID>1</auth:systemID>  
        <auth:userID>test</auth:userID>  
        <auth:password>test</auth:password>  
    </auth:authentication>  
</soap:Header>

一,首先在服務端建立一個攔截器(被調用端),須要繼承org.apache.cxf.phase.AbstractPhaseInterceptor  
代碼以下:  

import java.util.List;  
  
import javax.xml.soap.SOAPException;  
  
import org.apache.cxf.binding.soap.SoapHeader;  
import org.apache.cxf.binding.soap.SoapMessage;  
import org.apache.cxf.headers.Header;  
import org.apache.cxf.helpers.XMLUtils;  
import org.apache.cxf.interceptor.Fault;  
import org.apache.cxf.phase.AbstractPhaseInterceptor;  
import org.apache.cxf.phase.Phase;  
import org.apache.log4j.Logger;  
import org.w3c.dom.Element;  
import org.w3c.dom.NodeList;  
  
  
public class AuthIntercetpr extends AbstractPhaseInterceptor<SoapMessage> {  
    private static final Logger logger = Logger.getLogger(AuthIntercetpr.class);  
    public static final String xml_namespaceUR_att = "http://gd.chinamobile.com//authentication";  
    public static final String xml_header_el = "soap:Header";  
    public static final String xml_authentication_el = "auth:authentication";  
    public static final String xml_systemID_el = "auth:systemID";  
    public static final String xml_userID_el = "auth:userID";  
    public static final String xml_password_el = "auth:password";  
    public AuthIntercetpr() {  
        // 指定該攔截器在哪一個階段被激發  
        super(Phase.PRE_INVOKE);  
    }  
  
    // 處理消息  
    public void handleMessage(SoapMessage message) {  
        logger.info("==================SoapMessage =" + message);  
        // 獲取SOAP消息的所有頭  
        List<Header> headers = message.getHeaders();  
  
        if (null == headers || headers.size() < 1) {  
            throw new Fault(new SOAPException("SOAP消息頭格式不對哦!"));  
        }  
        for (Header header : headers) {  
            SoapHeader soapHeader = (SoapHeader) header;  
            // 取出SOAP的Header元素  
            Element element = (Element) soapHeader.getObject();  
            logger.info("ELEMENT =" + element.toString());  
            XMLUtils.printDOM(element);  
            NodeList userIdNodes = element  
                    .getElementsByTagName(xml_userID_el);  
            NodeList pwdNodes = element  
                    .getElementsByTagName(xml_password_el);  
            NodeList systemIdNodes = element  
                    .getElementsByTagName(xml_systemID_el);  
            logger.info("############ 打印賬號信息 ##############");  
            logger.info(userIdNodes.item(0) + "="  
                    + userIdNodes.item(0).getTextContent());  
            logger.info(systemIdNodes.item(0) + "="  
                    + systemIdNodes.item(0).getTextContent());  
            logger.info(pwdNodes.item(0) + "="  
                    + pwdNodes.item(0).getTextContent());  
            logger.info("############————————##############");  
            if (null != userIdNodes  
                    && userIdNodes.item(0).getTextContent().equels("test") ) {  
                if (null != pwdNodes  
                        && pwdNodes.item(0).getTextContent().equals("test")) {  
                    logger.info("$$$$$$$$ 認證成功");  
                } else {//認證失敗則拋出異常,中止繼續操做  
                    SOAPException soapExc = new SOAPException("閣下可能不是合法用戶!");  
                    throw new Fault(soapExc);  
                }  
            } else {//認證失敗則拋出異常,中止繼續操做  
                SOAPException soapExc = new SOAPException("閣下可能不是合法用戶!");  
                throw new Fault(soapExc);  
            }  
              
        }  
    }  
}

二,修改cxf-beans.xml 

<!--id:隨意配,implementor:指定接口具體實現類,address:隨意配,訪問時會用到,下面會作說明-->  
<!--攔截器-->  
<bean id="authIntercetpr" class="unitTest.AuthIntercetpr"></bean>  
<jaxws:endpoint id="HelloWorldService" implementor="com.ws.HelloWorldServiceImpl"  
        address="/IHelloService">  
        <!-- 在此配置調用當前ws所觸發的攔截器-->  
        <jaxws:inInterceptors><ref bean="authIntercetpr" /></bean>   
              
        <!--或者直接在這裏寫<bean  class="unitTest.AuthIntercetpr"></bean>-->  
        </jaxws:inInterceptors>  
</jaxws:endpoint>

到此服務端工做完畢!!!    apache

下面是客戶端(調用端)  

三,這邊一樣建立一個攔截器,實現org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor

import java.text.SimpleDateFormat;  
import java.util.Date;  
import java.util.List;  

import javax.xml.namespace.QName;  

import org.apache.cxf.binding.soap.SoapHeader;  
import org.apache.cxf.binding.soap.SoapMessage;  
import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;  
import org.apache.cxf.headers.Header;  
import org.apache.cxf.helpers.DOMUtils;  
import org.apache.cxf.helpers.XMLUtils;  
import org.apache.cxf.interceptor.Fault;  
import org.apache.cxf.phase.Phase;  
import org.w3c.dom.Document;  
import org.w3c.dom.Element;  
  
public class AddSoapHeader extends AbstractSoapInterceptor {  
  
    public static final String xml_namespaceUR_att = "http://gd.chinamobile.com//authentication";  
    public static final String xml_header_el = "soap:Header";  
    public static final String xml_authentication_el = "auth:authentication";  
    public static final String xml_systemID_el = "auth:systemID";  
    public static final String xml_userID_el = "auth:userID";  
    public static final String xml_password_el = "auth:password";  
  
    public AddSoapHeader() {  
    // 指定該攔截器在哪一個階段被激發  
        super(Phase.WRITE);  
    }  
  
    public void handleMessage(SoapMessage message) throws Fault {  
        SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
        Date date = new Date();  
        String time = sd.format(date);  
        String userId = "test";  
        String sysId = "1";  
        String password = "test";  
  
        QName qname = new QName("RequestSOAPHeader");//這個值暫時不清楚具體作什麼用,能夠隨便寫  
  
        Document doc = (Document) DOMUtils.createDocument();  
        Element root = doc.createElement(xml_header_el);  
        Element eSysId = doc.createElement(xml_systemID_el);  
        eSysId.setTextContent(sysId);  
        Element eUserId = doc.createElement(xml_userID_el);  
        eUserId.setTextContent(userId);  
        Element ePwd = doc.createElement(xml_password_el);  
        ePwd.setTextContent(password);  
        Element child = doc.createElementNS(xml_namespaceUR_att,  
                xml_authentication_el);  
        child.appendChild(eSysId);  
        child.appendChild(eUserId);  
        child.appendChild(ePwd);  
        root.appendChild(child);  
        XMLUtils.printDOM(root);// 只是打印xml內容到控制檯,可刪除  
        SoapHeader head = new SoapHeader(qname, root);  
        List<Header> headers = message.getHeaders();  
        headers.add(head);  
          
    }  
  
}

四,具體調用ws的類代碼

private static final String webServiceConTimeout = "6000";  
private static final String webServiceRevTimeout = "6000";  
  
HelloWorldServiceImplService hello = new HelloWorldServiceImplService();    
HelloWorldService service = hello.getHelloWorldServiceImplPort();  
//以上什麼意思請參考:http://learning.iteye.com/admin/blogs/1333223  
Client clientProxy = ClientProxy.getClient(service);//經過目標ws獲取代理  
//注入攔截器,getOutInterceptors表明調用服務端時觸發,getInInterceptors就是被調用才觸發  
clientProxy.getOutInterceptors().add(ash);  
// 超時時間設置  
HTTPConduit http = (HTTPConduit) clientProxy.getConduit();  
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();  
httpClientPolicy.setConnectionTimeout(Integer  
		.valueOf(webServiceConTimeout));  
httpClientPolicy.setReceiveTimeout(Integer  
		.valueOf(webServiceRevTimeout));  
httpClientPolicy.setAllowChunking(false);  
http.setClient(httpClientPolicy);  
//以上插入點超時設置方式  
//下面這行代碼是具體調用服務段的deleteTeskTask()  
CallResult cResult = service.deleteTeskTask("1223");

客戶端代碼到此結束 安全

五,還有一種方式是經過JaxWsProxyFactoryBean方式,註冊攔截器及實例化ws,代碼以下:   

private static final JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();  
  
AddSoapHeader ash = new AddSoapHeader();  
ArrayList list = new ArrayList();  
// 添加soap header 信息  
list.add(ash);  
//注入攔截器,getOutInterceptors表明調用服務端時觸發,getInInterceptors就是被調用才觸發  
 factory.setOutInterceptors(list);  
 factory.setServiceClass(HelloWorldService.class);//實例化ws  
 factory.setAddress("http://xxx.xxx.xxx.xxx:8004/services/IHelloService");  
 Object obj = factory.create();  
 HelloWorldService service = (HelloWorldService) obj;  
 //下面這行代碼是具體調用服務段的deleteTeskTask()  
CallResult cResult = service.deleteTeskTask("1223");
##########這段代碼可替代步驟(四)#####      到此所有工做結束   具體一些概念還請本身baidu/google  
相關文章
相關標籤/搜索