• 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
         */
        @Override
        public 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
         */
        @Override
        public 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);// 实例化ws
            factory.setAddress("http://localhost:8090/iwm/sapDeliveryOrderToIwm");
            Object obj = factory.create();
            HelloWorldService service = (HelloWorldService) obj;
            //下面这行代码是具体调用服务段的deleteTeskTask()
            CallResult cResult = service.deleteTeskTask("1223");
    客户端代码到此结束
  • 相关阅读:
    C# CefSharp
    C# CRC16 modbus
    C++ 调试信息输出
    运行elasticsearch.bat出错
    Windows下NodeJS安装与npm环境变量配置
    Rescue
    Catch That Cow
    7.3.1 Swagger 文档生成工具
    3.并发处理
    2.集合处理
  • 原文地址:https://www.cnblogs.com/rinack/p/7922004.html
Copyright © 2020-2023  润新知