CXF 入门:创建一个基于SOAPHeader的安全验证(CXF拦截器使用)
生活随笔
收集整理的這篇文章主要介紹了
CXF 入门:创建一个基于SOAPHeader的安全验证(CXF拦截器使用)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
CXF攔截器使用,創建一個使用SOAPHeader的安全驗證
xml格式: <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.namespace.QName;import org.apache.cxf.binding.soap.SoapMessage; import org.apache.cxf.headers.Header; 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 AuthValidateInterceptor extends AbstractPhaseInterceptor<SoapMessage> {private Logger logger = Logger.getLogger(this.getClass());public AuthValidateInterceptor() {// 定義攔截器階段super(Phase.PRE_INVOKE);}/*** @Description: 攔截器操作* @param message* 被攔截到的消息* @throws Fault*/@Overridepublic void handleMessage(SoapMessage message) {List<Header> headers = message.getHeaders();if (headers == null || headers.isEmpty()) {throw new Fault(new Exception("無授權信息!"));}Element auth = null;// 獲取授權信息元素for (Header header : headers) {QName qname = header.getName();String tagName = qname.getLocalPart();if (tagName != null && tagName.equals("auth")) {auth = (Element) header.getObject();break;}}// 如果授權信息元素不存在,提示錯誤if (auth == null) {throw new Fault(new Exception("無授權信息!"));}NodeList nameList = auth.getElementsByTagName("username");NodeList pwdList = auth.getElementsByTagName("password");if (nameList.getLength() != 1 || pwdList.getLength() != 1) {throw new Fault(new Exception("授權信息錯誤!"));}String name = nameList.item(0).getTextContent();String password = pwdList.item(0).getTextContent();if (!"admin".equals(name) || !"admin".equals(password)) {throw new Fault(new Exception("授權信息錯誤!"));}}} 二,修改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>到此服務端工作完畢!!! 下面是客戶端(調用端) 三,這邊同樣創建一個攔截器,實現org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor 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.interceptor.Fault; import org.apache.cxf.phase.Phase; import org.apache.log4j.Logger; import org.w3c.dom.Document; import org.w3c.dom.Element;/*** 系統全局攔截器(排除登錄服務調用) 用于校驗登錄的賬號是否已登錄* */ public class ClientAuthValidateInterceptor extends AbstractSoapInterceptor {private Logger logger = Logger.getLogger(this.getClass());public static final String xml_namespaceUR = "";public static final String xml_header = "soap:Header";public static final String xml_authentication = "auth:authentication";public static final String xml_systemID = "auth:systemID";public static final String xml_username = "auth:username";public static final String xml_password = "auth:password";public ClientAuthValidateInterceptor() {// 定義攔截器階段super(Phase.WRITE);}/*** @Description: 攔截器操作* @param message* 被攔截到的消息* @throws Fault*/@Overridepublic void handleMessage(SoapMessage message) {String userId = "test";String sysId = "1";String password = "test";Document doc = DOMUtils.createDocument();Element root = doc.createElement(xml_header);Element eSysId = doc.createElement(xml_systemID);eSysId.setTextContent(sysId);Element eUserId = doc.createElement(xml_username);eUserId.setTextContent(userId);Element ePwd = doc.createElement(xml_password);ePwd.setTextContent(password);Element child = doc.createElementNS(xml_namespaceUR, xml_authentication);child.appendChild(eSysId);child.appendChild(eUserId);child.appendChild(ePwd);root.appendChild(child);QName qname = new QName("RequestSOAPHeader");SoapHeader head = new SoapHeader(qname, root);List<Header> headers = message.getHeaders();headers.add(head);}} 四,具體調用ws的類代碼 HelloWorldServiceImplService hello = new HelloWorldServiceImplService(); HelloWorldService service = hello.getHelloWorldServiceImplPort();// 插入身份驗證Client clientProxy = ClientProxy.getClient(port);// 通過目標ws獲取代理// 注入攔截器,getOutInterceptors代表調用服務端時觸發,getInInterceptors就是被調用才觸發clientProxy.getOutInterceptors().add(new ClientAuthValidateInterceptor());// 超時時間設置HTTPConduit http = (HTTPConduit) clientProxy.getConduit();HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();httpClientPolicy.setConnectionTimeout(Integer.valueOf("6000"));httpClientPolicy.setReceiveTimeout(Integer.valueOf("6000"));httpClientPolicy.setAllowChunking(false);http.setClient(httpClientPolicy);//下面這行代碼是具體調用服務段的deleteTeskTask()CallResult cResult = service.deleteTeskTask("1223");
xml格式: <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.namespace.QName;import org.apache.cxf.binding.soap.SoapMessage; import org.apache.cxf.headers.Header; 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 AuthValidateInterceptor extends AbstractPhaseInterceptor<SoapMessage> {private Logger logger = Logger.getLogger(this.getClass());public AuthValidateInterceptor() {// 定義攔截器階段super(Phase.PRE_INVOKE);}/*** @Description: 攔截器操作* @param message* 被攔截到的消息* @throws Fault*/@Overridepublic void handleMessage(SoapMessage message) {List<Header> headers = message.getHeaders();if (headers == null || headers.isEmpty()) {throw new Fault(new Exception("無授權信息!"));}Element auth = null;// 獲取授權信息元素for (Header header : headers) {QName qname = header.getName();String tagName = qname.getLocalPart();if (tagName != null && tagName.equals("auth")) {auth = (Element) header.getObject();break;}}// 如果授權信息元素不存在,提示錯誤if (auth == null) {throw new Fault(new Exception("無授權信息!"));}NodeList nameList = auth.getElementsByTagName("username");NodeList pwdList = auth.getElementsByTagName("password");if (nameList.getLength() != 1 || pwdList.getLength() != 1) {throw new Fault(new Exception("授權信息錯誤!"));}String name = nameList.item(0).getTextContent();String password = pwdList.item(0).getTextContent();if (!"admin".equals(name) || !"admin".equals(password)) {throw new Fault(new Exception("授權信息錯誤!"));}}} 二,修改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>到此服務端工作完畢!!! 下面是客戶端(調用端) 三,這邊同樣創建一個攔截器,實現org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor 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.interceptor.Fault; import org.apache.cxf.phase.Phase; import org.apache.log4j.Logger; import org.w3c.dom.Document; import org.w3c.dom.Element;/*** 系統全局攔截器(排除登錄服務調用) 用于校驗登錄的賬號是否已登錄* */ public class ClientAuthValidateInterceptor extends AbstractSoapInterceptor {private Logger logger = Logger.getLogger(this.getClass());public static final String xml_namespaceUR = "";public static final String xml_header = "soap:Header";public static final String xml_authentication = "auth:authentication";public static final String xml_systemID = "auth:systemID";public static final String xml_username = "auth:username";public static final String xml_password = "auth:password";public ClientAuthValidateInterceptor() {// 定義攔截器階段super(Phase.WRITE);}/*** @Description: 攔截器操作* @param message* 被攔截到的消息* @throws Fault*/@Overridepublic void handleMessage(SoapMessage message) {String userId = "test";String sysId = "1";String password = "test";Document doc = DOMUtils.createDocument();Element root = doc.createElement(xml_header);Element eSysId = doc.createElement(xml_systemID);eSysId.setTextContent(sysId);Element eUserId = doc.createElement(xml_username);eUserId.setTextContent(userId);Element ePwd = doc.createElement(xml_password);ePwd.setTextContent(password);Element child = doc.createElementNS(xml_namespaceUR, xml_authentication);child.appendChild(eSysId);child.appendChild(eUserId);child.appendChild(ePwd);root.appendChild(child);QName qname = new QName("RequestSOAPHeader");SoapHeader head = new SoapHeader(qname, root);List<Header> headers = message.getHeaders();headers.add(head);}} 四,具體調用ws的類代碼 HelloWorldServiceImplService hello = new HelloWorldServiceImplService(); HelloWorldService service = hello.getHelloWorldServiceImplPort();// 插入身份驗證Client clientProxy = ClientProxy.getClient(port);// 通過目標ws獲取代理// 注入攔截器,getOutInterceptors代表調用服務端時觸發,getInInterceptors就是被調用才觸發clientProxy.getOutInterceptors().add(new ClientAuthValidateInterceptor());// 超時時間設置HTTPConduit http = (HTTPConduit) clientProxy.getConduit();HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();httpClientPolicy.setConnectionTimeout(Integer.valueOf("6000"));httpClientPolicy.setReceiveTimeout(Integer.valueOf("6000"));httpClientPolicy.setAllowChunking(false);http.setClient(httpClientPolicy);//下面這行代碼是具體調用服務段的deleteTeskTask()CallResult cResult = service.deleteTeskTask("1223");
五,還有一種方式是通過JaxWsProxyFactoryBean方式,注冊攔截器及實例化ws,代碼如下:
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();List<Interceptor<? extends Message>> clientAuthValidateInterceptors = new ArrayList<>();// 添加soap header 信息clientAuthValidateInterceptors.add(new ClientAuthValidateInterceptor());// 注入攔截器,getOutInterceptors代表調用服務端時觸發,getInInterceptors就是被調用才觸發 factory.setOutInterceptors(clientAuthValidateInterceptors);factory.setServiceClass(HelloWorldService.class);// 實例化wsfactory.setAddress("http://localhost:8090/iwm/sapDeliveryOrderToIwm");Object obj = factory.create();HelloWorldService service = (HelloWorldService) obj;//下面這行代碼是具體調用服務段的deleteTeskTask()CallResult cResult = service.deleteTeskTask("1223"); 客戶端代碼到此結束轉載于:https://www.cnblogs.com/rinack/p/7922004.html
總結
以上是生活随笔為你收集整理的CXF 入门:创建一个基于SOAPHeader的安全验证(CXF拦截器使用)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: POJ2417 Discrete Log
- 下一篇: 【十九】require和include的