WebService(7)_Apache CXF拦截器-权限管理-登录验证
发布时间:2020-12-16 21:54:36 所属栏目:安全 来源:网络整理
导读:上一篇提到过CXF的安全性问题.. 这里提供一个解决思路,在调用CXF服务端的时候,进行用户校验.这样子似乎能提高一些安全.. 正式项目使用的话,用户名和密码都要MD5加密..? 不过使用用户名和密码,还是有一点 "伪安全"的意思..? 别人要是抓个包... 不全部歇菜嘛..
上一篇提到过CXF的安全性问题.. 这里提供一个解决思路,在调用CXF服务端的时候,进行用户校验.这样子似乎能提高一些安全.. 正式项目使用的话,用户名和密码都要MD5加密..? 不过使用用户名和密码,还是有一点 "伪安全"的意思..? 别人要是抓个包... 不全部歇菜嘛.. 不废话了.. 先把工程代码贴上来.. 下载之后可以直接运行. CXF-拦截器-权限控制-登录校验 服务端接口 package com.cxf.inter; import javax.jws.WebService; @WebService public interface CXFInterface { public String sayHello(String name); } package com.cxf.inter; import javax.jws.WebService; @WebService public class CXFDemoImpl implements CXFInterface { @Override public String sayHello(String name) { return "Interceptor Hello : " + name; } } package com.cxf; import java.util.List; 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.w3c.dom.Element; import org.w3c.dom.NodeList; public class AuthInterceptor extends AbstractPhaseInterceptor<SoapMessage> { // 在拦截器调用方法之前,拦截SOAP消息. public AuthInterceptor() { super(Phase.PRE_INVOKE); } @Override /** * 拦截器处理方法 */ public void handleMessage(SoapMessage message) throws Fault { System.out.println("---- 进入拦截器 ----"); // 获取SOAP携带的所有Header List<Header> headers = message.getHeaders(); if (null == headers || headers.size() < 1) throw new Fault(new IllegalArgumentException("拦截器实施拦截,没有Header")); // 获取Header携带的用户名和密码 Header firstHeader = headers.get(0); Element element = (Element) firstHeader.getObject(); NodeList userNameElement = element.getElementsByTagName("userName"); NodeList passWordElement = element.getElementsByTagName("passWord"); if (userNameElement.getLength() != 1) throw new Fault(new IllegalArgumentException("用户名不能为空..")); if (passWordElement.getLength() != 1) throw new Fault(new IllegalArgumentException("密码不能为空..")); // 获取元素中的文本内容 String username = userNameElement.item(0).getTextContent(); String password = passWordElement.item(0).getTextContent(); // 实际项目中,是从数据库中取数据做校验 if (!username.equals("cyx") || !password.equals("123456")) { throw new Fault(new IllegalArgumentException("用户名或密码不正确..")); } else { System.out.println("验证成功!!"); } } } 服务端发布主类 package com.cxf; import javax.xml.ws.Endpoint; import org.apache.cxf.jaxws.EndpointImpl; import com.cxf.inter.CXFDemoImpl; /** * CXF拦截器<br> * 通过拦截器,进行用户校验. * * @author CYX * */ public class StartMain { public static void main(String[] args) { String address = "http://localhost:8088/CXFDemo/sayHello"; EndpointImpl epi = (EndpointImpl) Endpoint.publish(address,new CXFDemoImpl()); epi.getInInterceptors().add(new AuthInterceptor()); System.out.println("WebService 发布成功,address : " + address); } } 通过wsdl生成客户端代码就不多说了..去看以前的文章吧... 客户端拦截器 package com.client.interceptor; 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.helpers.DOMUtils; import org.apache.cxf.interceptor.Fault; import org.apache.cxf.phase.AbstractPhaseInterceptor; import org.apache.cxf.phase.Phase; import org.w3c.dom.Document; import org.w3c.dom.Element; /** * 客户端拦截器 * * @author CYX * */ public class AddHeaderInterceptor extends AbstractPhaseInterceptor<SoapMessage> { private String userName; private String passWord; public AddHeaderInterceptor(String username,String password) { super(Phase.PREPARE_SEND); this.userName = username; this.passWord = password; } @Override public void handleMessage(SoapMessage message) throws Fault { List<Header> header = message.getHeaders(); // 创建Document对象 Document document = DOMUtils.createDocument(); Element element = document.createElement("authHeader"); // 配置服务端Head信息的用户名和密码 Element userNameElement = document.createElement("userName"); userNameElement.setTextContent(userName); Element passWordElement = document.createElement("passWord"); passWordElement.setTextContent(passWord); element.appendChild(userNameElement); element.appendChild(passWordElement); header.add(new Header(new QName(""),element)); } } package com.client; import org.apache.cxf.endpoint.Client; import org.apache.cxf.frontend.ClientProxy; import com.client.interceptor.AddHeaderInterceptor; import com.cxf.inter.CXFDemoImplService; import com.cxf.inter.CXFInterface; public class TestClient { public static void main(String[] args) { CXFDemoImplService cxfDemo = new CXFDemoImplService(); CXFInterface cxfInter = cxfDemo.getCXFDemoImplPort(); Client client = ClientProxy.getClient(cxfInter); client.getOutInterceptors().add(new AddHeaderInterceptor("cy","123456")); String response = cxfInter.sayHello("xycheng"); System.out.println("response : " + response); } }这里的'cyx' 和 '123456' 要和服务端拦截器中的相匹配..? 正式项目肯定是通过数据库验证.. 然后直接运行服务端和客户端就行了... 密码错误 服务端控制台打印 客户端控制台打印信息 密码争取的控制台打印信息 服务端 客户端 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |