WebService(7)_Apache CXF拦截器-权限管理-登录验证

来源:互联网 发布:风险评价矩阵法 编辑:程序博客网 时间:2024/06/08 18:57

上一篇提到过CXF的安全性问题..

这里提供一个解决思路 , 在调用CXF服务端的时候,进行用户校验.这样子似乎能提高一些安全..

正式项目使用的话, 用户名和密码都要MD5加密.. 

不过使用用户名和密码 , 还是有一点 "伪安全"的意思.. 

别人要是抓个包... 不全部歇菜嘛..

不废话了.. 先把工程代码贴上来.. 下载之后可以直接运行.

CXF-拦截器-权限控制-登录校验


服务端接口

package com.cxf.inter;import javax.jws.WebService;@WebServicepublic interface CXFInterface {public String sayHello(String name);}


接口实现类

package com.cxf.inter;import javax.jws.WebService;@WebServicepublic class CXFDemoImpl implements CXFInterface {@Overridepublic 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携带的所有HeaderList<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;}@Overridepublic 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' 要和服务端拦截器中的相匹配.. 

正式项目肯定是通过数据库验证..

然后直接运行服务端和客户端就行了...


密码错误

服务端控制台打印


客户端控制台打印信息




密码争取的控制台打印信息

服务端


客户端



0 0
原创粉丝点击