JAX-WS使用Handler实现简单的WebService权限验证
WebService如果涉及到安全保密或者使用权限的时候,WS-Security通常是最优选择。WS-Security (Web服务安全)
包含了关于如何在WebService消息上保证完整性和机密性的规约,如何将签名和加密头加入SOAP消息。
不过WS-Security也有一些性能上的损耗,在信息保密要求不是很高的情况下,可以通过在SOAPHeader中添加简单的校验信息实现。
具体思路是客户端调用需要认证的服务时,在SOAPHeader中添加授权信息(如用户名、密码或者序列号等)。
服务端收到请求,在SOAPHeader中校验授权信息,校验通过则执行请求,校验不通过则返回错误提示。
客户端发起请求在SOAPHeader中添加的授权数据格式如下
<authxmlns="http://schemas.xmlsoap.org/soap/actor/next"> <username>admin</username> <password>admin</password> </auth>
服务端
服务端授权校验 Handler
importjava.util.Iterator;importjava.util.Set;importjavax.xml.namespace.QName;importjavax.xml.soap.SOAPBody;importjavax.xml.soap.SOAPConstants;importjavax.xml.soap.SOAPElement;importjavax.xml.soap.SOAPEnvelope;importjavax.xml.soap.SOAPException;importjavax.xml.soap.SOAPFault;importjavax.xml.soap.SOAPHeader;importjavax.xml.soap.SOAPMessage;importjavax.xml.ws.handler.MessageContext;importjavax.xml.ws.handler.soap.SOAPHandler;importjavax.xml.ws.handler.soap.SOAPMessageContext;importorg.apache.cxf.interceptor.Fault;importorg.w3c.dom.NodeList;/****@author */ public class JaxServerAuthValidateHeader implements SOAPHandler<SOAPMessageContext>{@Overridepublic voidclose(MessageContext context) {}@Overridepublic booleanhandleFault(SOAPMessageContext context) {return true;}@Overridepublic booleanhandleMessage(SOAPMessageContext context) {//判断消息是输入还是输出boolean isRequest =(Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);SOAPMessage soapMessage=context.getMessage();if (!isRequest) {SOAPHeader soapHeader= null;try{SOAPEnvelope soapEnv=soapMessage.getSOAPPart().getEnvelope();soapHeader=soapEnv.getHeader();}catch(SOAPException e) {throw new Fault(new Exception("服务器异常!"));}if (soapHeader == null) {validateFail(soapMessage,"无 Soap Header 头信息!");return false;}//add an node named "auth"QName qname = new QName(SOAPConstants.URI_SOAP_ACTOR_NEXT, "auth");Iterator<?> iterator =soapHeader.getChildElements(qname);SOAPElement auth= null;if(iterator.hasNext()) {//获取authauth =(SOAPElement) iterator.next();}//如果授权信息元素不存在,提示错误if (auth == null) {validateFail(soapMessage,"无授权信息!");return false;}NodeList nameList= auth.getElementsByTagName("username");NodeList pwdList= auth.getElementsByTagName("password");if (nameList == null || nameList.getLength() <= 0 || pwdList == null || pwdList.getLength() <= 0) {validateFail(soapMessage,"授权信息格式错误!");return false;}String username= nameList.item(0).getTextContent();String password= pwdList.item(0).getTextContent();if (!"admin".equals(username) || !"admin".equals(password)) {validateFail(soapMessage,"授权信息格式错误!");return false;}}System.out.println(isRequest? "服务端响应:" : "服务端接收:");System.out.println("\r\n");return true;}@Overridepublic Set<QName>getHeaders() {return null;}/*** 授权校验失败,在SOAPBody中添加SOAPFault* *@parammessage*/private voidvalidateFail(SOAPMessage soapMessage, String faultString) {try{SOAPEnvelope envelop=soapMessage.getSOAPPart().getEnvelope();envelop.getHeader().detachNode();envelop.addHeader();envelop.getBody().detachNode();SOAPBody body=envelop.addBody();SOAPFault fault=body.getFault();if (fault == null) {fault=body.addFault();}fault.setFaultString(faultString);soapMessage.saveChanges();}catch(SOAPException e) {e.printStackTrace();}}}
服务端Handler配置文件handler-chain.xml
<?xml version="1.0" encoding="UTF-8"?> <javaee:handler-chainsxmlns:javaee="http://java.sun.com/xml/ns/javaee"xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <javaee:handler-chain> <javaee:handler> <javaee:handler-class>com.server.handler.JaxServerAuthValidateHeader</javaee:handler-class> </javaee:handler> </javaee:handler-chain> </javaee:handler-chains>
服务端的Service中添加Handler配置文件
importjavax.jws.WebMethod;importjavax.jws.WebParam;importjavax.jws.WebResult;importjavax.jws.WebService;importjavax.xml.bind.annotation.XmlSeeAlso;importjavax.xml.ws.RequestWrapper;importjavax.xml.ws.ResponseWrapper;/*** This class was generated by Apache CXF 3.2.1* 2017-12-01T14:12:00.085+08:00* Generated source version: 3.2.1**/@WebService(targetNamespace= "http://tempuri.org/", name = "AExampleDemoWebService") @HandlerChain(file="handler-chain.xml")public interfaceAExampleDemoWebService {@WebMethod@WebResult(name= "single", targetNamespace = "")publicjava.lang.String querySingle(@WebParam(name= "single", targetNamespace = "http://tempuri.org/")java.lang.String single);}
服务端的Service 实现类
importjava.util.ArrayList;importjava.util.List;importcn.evun.iwm.receive.soap.service.AExampleDemoWebService;importcn.evun.iwm.receive.soap.struc.sample.InputParam;importcn.evun.iwm.receive.soap.struc.sample.OutputParam;@javax.jws.WebService(serviceName= "aexampleDemoWebService", portName = "Sample", targetNamespace= "http://tempuri.org/", endpointInterface = "cn.soap.service.AExampleDemoWebService")public class AExampleDemoWebServiceImpl implementsAExampleDemoWebService {@OverridepublicString querySingle(String input) {return "success";}}
客户端
客户端添加授权Handler
importjava.io.IOException;importjava.util.Set;importjavax.xml.namespace.QName;importjavax.xml.soap.SOAPConstants;importjavax.xml.soap.SOAPElement;importjavax.xml.soap.SOAPException;importjavax.xml.soap.SOAPHeader;importjavax.xml.soap.SOAPMessage;importjavax.xml.ws.handler.MessageContext;importjavax.xml.ws.handler.soap.SOAPHandler;importjavax.xml.ws.handler.soap.SOAPMessageContext;public class JaxWsClientHandler implements SOAPHandler<SOAPMessageContext>{@Overridepublic booleanhandleMessage(SOAPMessageContext context) {//判断消息是请求还是响应Boolean isRequest =(Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);SOAPMessage soapMessage=context.getMessage();if(isRequest) {try{SOAPHeader soapHeader=soapMessage.getSOAPHeader();if (soapHeader == null) { soapHeader=soapMessage.getSOAPPart().getEnvelope().addHeader(); }//add an node named "auth"QName qname = new QName(SOAPConstants.URI_SOAP_ACTOR_NEXT, "auth");SOAPElement auth=soapHeader.addChildElement(qname);SOAPElement name= auth.addChildElement("username");name.addTextNode("admin");SOAPElement password= auth.addChildElement("password");password.addTextNode("admin");soapMessage.saveChanges();//tracking soapMessage.writeTo(System.out);}catch(SOAPException e) {System.err.println(e);}catch(IOException e) {System.err.println(e);}}return true;}@Overridepublic booleanhandleFault(SOAPMessageContext context) {return false;}@Overridepublic voidclose(MessageContext context) {}@Overridepublic Set<QName>getHeaders() {return null;}}
客户端Handler配置文件handler-chain.xml
<?xml version="1.0" encoding="UTF-8"?> <javaee:handler-chainsxmlns:javaee="http://java.sun.com/xml/ns/javaee"xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <javaee:handler-chain> <javaee:handler> <javaee:handler-class>com.client.handler.JaxWsClientHandler</javaee:handler-class> </javaee:handler> </javaee:handler-chain> </javaee:handler-chains>
客户端的Service中添加Handler配置文件
importjava.net.MalformedURLException;importjava.net.URL;importjavax.xml.namespace.QName;importjavax.xml.ws.WebEndpoint;importjavax.xml.ws.WebServiceClient;importjavax.xml.ws.WebServiceFeature;importjavax.xml.ws.Service;/*** This class was generated by Apache CXF 3.2.1* 2017-12-01T14:12:00.117+08:00* Generated source version: 3.2.1**/@WebServiceClient(name= "aexampleDemoWebService", wsdlLocation= "http://localhost:8090/service/Sample?wsdl",targetNamespace= "http://tempuri.org/") @HandlerChain(file="handler-chain.xml")public class AexampleDemoWebServiceSoap extendsService {public final staticURL WSDL_LOCATION;public final static QName SERVICE = new QName("http://tempuri.org/", "aexampleDemoWebService");public final static QName Sample = new QName("http://tempuri.org/", "Sample");static{URL url= null;try{url= new URL("http://localhost:8090/service/Sample?wsdl");}catch(MalformedURLException e) {java.util.logging.Logger.getLogger(AexampleDemoWebServiceSoap.class.getName()).log(java.util.logging.Level.INFO,"Can not initialize the default wsdl from {0}", "http://localhost:8090/service/Sample?wsdl");}WSDL_LOCATION=url;}publicAexampleDemoWebServiceSoap(URL wsdlLocation) {super(wsdlLocation, SERVICE);}publicAexampleDemoWebServiceSoap(URL wsdlLocation, QName serviceName) {super(wsdlLocation, serviceName);}publicAexampleDemoWebServiceSoap() {super(WSDL_LOCATION, SERVICE);}publicAexampleDemoWebServiceSoap(WebServiceFeature ... features) {super(WSDL_LOCATION, SERVICE, features);}publicAexampleDemoWebServiceSoap(URL wsdlLocation, WebServiceFeature ... features) {super(wsdlLocation, SERVICE, features);}publicAexampleDemoWebServiceSoap(URL wsdlLocation, QName serviceName, WebServiceFeature ... features) {super(wsdlLocation, serviceName, features);}/****@return* returns AExampleDemoWebService*/@WebEndpoint(name= "Sample")publicAExampleDemoWebService getSample() {return super.getPort(Sample, AExampleDemoWebService.class);}/*** *@paramfeatures* A list of {@linkjavax.xml.ws.WebServiceFeature} to configure on the proxy. * Supported features not in the <code>features</code> parameter will have their default values.*@return* returns AExampleDemoWebService*/@WebEndpoint(name= "Sample")publicAExampleDemoWebService getSample(WebServiceFeature... features) {return super.getPort(Sample, AExampleDemoWebService.class, features);}}
客户端发起请求
QName SERVICE_NAME = new QName("http://tempuri.org/", "aexampleDemoWebService"); URL url= new URL("http://localhost:8090/service/Sample?wsdl"); AexampleDemoWebServiceSoap ss= newAexampleDemoWebServiceSoap(wsdlURL, SERVICE_NAME); AExampleDemoWebService port=ss.getSample(); port.querySingle("1111");
@HandlerChain 注解 替代方式
客户端 通过 HandlerReolver 代替 @HandlerChain 注解 导入 Handler 配置文件
handler-chain配置文件对所有的请求都添加授权验证信息,有些时候不是所有的请求都需要添加授权验证,HandlerResolver提供了在编程时添加Handler的方法,可以用HandlerResolver给需要授权的接口添加Handler。
QName SERVICE_NAME = new QName("http://tempuri.org/", "aexampleDemoWebService"); URL url= new URL("http://localhost:8090/service/Sample?wsdl"); AexampleDemoWebServiceSoap ss= newAexampleDemoWebServiceSoap(wsdlURL, SERVICE_NAME);//通过HandlerResolver添加Handler ss.setHandlerResolver(newHandlerResolver(){ @Override @SuppressWarnings("rawtypes")public List<Handler>getHandlerChain(PortInfo portInfo) { List<Handler> handlerChain = new ArrayList<Handler>(); handlerChain.add(newJaxWsClientHandler());returnhandlerChain; } }); AExampleDemoWebService port=ss.getSample(); port.querySingle("2222");
服务端 @HandlerChain 注解替代
服务发布时服务端通过继承至 Endpoint 实现类 EndpointImpl 的 setHandlers 方法添加头部信息 代替 @HandlerChain 注解 导入 Handler 配置文件
importjava.util.ArrayList;importjava.util.List;importjavax.xml.ws.Endpoint;importjavax.xml.ws.handler.Handler;importorg.apache.cxf.Bus;importorg.apache.cxf.bus.spring.SpringBus;importorg.apache.cxf.interceptor.Interceptor;importorg.apache.cxf.jaxws.EndpointImpl;importorg.apache.cxf.message.Message;importorg.apache.cxf.transport.servlet.CXFServlet;importorg.springframework.boot.context.embedded.ServletRegistrationBean;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;@Configurationpublic classCXFConfig {@BeanpublicServletRegistrationBean dispatcherServlet() {return new ServletRegistrationBean(new CXFServlet(), "/service/*");}@Bean(name=Bus.DEFAULT_BUS_ID)publicSpringBus springBus() {return newSpringBus();}@BeanpublicAExampleDemoWebServiceImpl aExampleDemoWebServiceImpl() {return newAExampleDemoWebServiceImpl();}@BeanpublicEndpoint endpointWebServiceSampleImpl() {EndpointImpl endpoint= newEndpointImpl(springBus(), aExampleDemoWebServiceImpl());//SOAPHandler 方式@SuppressWarnings("rawtypes")List<Handler> handlers = new ArrayList<>();handlers.add(newJaxServerAuthValidateHeader());endpoint.setHandlers(handlers);endpoint.publish("/Sample");returnendpoint;}}
当使用替代方式添加头部信息的时候就不需要使用 @HandlerChain 注解
转载于:https://www.cnblogs.com/rinack/p/7943164.html
JAX-WS使用Handler实现简单的WebService权限验证相关推荐
- spring和maven_具有Spring和Maven教程的JAX–WS
spring和maven Spring框架通过JAX-WS提供对Web服务的远程支持,实际上,如Spring 参考文档中所述 ,有三种将Spring POJO服务公开为JAX-WS Web服务的方式: ...
- 带有Spring和Maven教程的JAX–WS
Spring框架通过JAX-WS提供对Web服务的远程支持,实际上,如Spring 参考文档中所述 ,有三种将Spring POJO服务公开为JAX-WS Web服务的方式: 公开基于Servlet的 ...
- [WS]使用Axis发布简单的Web服务
使用Axis,要发布一个Web服务非常简单,简直不能再简单了,尽管看起来过程和相关代码有些长.我这个帖子里用到了这些软件:Axis 1.1.Eclipse 2.1和Eclipse的Tomcat插件2. ...
- 一个简单的Webservice的demo,简单模拟服务
前段时间一直在学习WCF,匆匆忙忙的把<WCF全面解析>和<WCF服务编程>看了一遍,好多东西都不是很懂,又听了一下WCF分布式开发的网络教程,算是马马虎虎的明白点了.回顾了一 ...
- 简单的webService实例
参看博文:http://nopainnogain.iteye.com/blog/791525 项目的源码与所有jar包:http://pan.baidu.com/s/1qXQuDtE 本文主要是在原来 ...
- 使用Axis2创建一个简单的WebService服务
使用过Java进行过WebService开发都会听过或者接触过Apache Axis2,Axis2框架是应用最广泛的WebService框架之一了. 这里使用Axis2来开发和部署一个最简单的WebS ...
- 一个简单的Webservice的demo(中)_前端页面调用
首先新建项目,这里有两种调用方式,为了能方便理解,新建页面WebserviceTest如下图: 先引用写好的服务,这里用上次写好的服务.见上次写的一个简单的Webservice的demo,简单模拟服务 ...
- Web Service入门简介(一个简单的WebService示例)
一.Web Service简介 1.1.Web Service基本概念 Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intrane ...
- 使用 PyTorch 数据读取,JAX 框架来训练一个简单的神经网络
使用 PyTorch 数据读取,JAX 框架来训练一个简单的神经网络 本文例程部分主要参考官方文档. JAX简介 JAX 的前身是 Autograd ,也就是说 JAX 是 Autograd 升级版本 ...
最新文章
- java前端目录_[Java教程]前端那点事儿——Tocify自动生成文档目录
- taglib遍历foreach循环list集合
- python基础学习[python编程从入门到实践读书笔记(连载二)]:外星人入侵项目
- 【quartus】原理图输入设计详解攻略
- XDeepFM高阶特征交互,特征交互:一种极深因子分解机模型
- Feign 重试解析
- 拓端tecdat|R语言ARMA GARCH COPULA模型拟合股票收益率时间序列和模拟可视化
- XLSTransformer+模板 导出 Excel
- FSG压缩壳和ImportREC的使用 - 脱壳篇05
- 如何将PayPal中的美元以人民币的形式提现到建设银行卡中?
- [35期] 没有硝烟的战争
- 音频信号处理——基音周期
- 微信公众平台数据统计
- 如果宁静是Oracle,那万茜,张雨绮,黄圣依 是什么?(附姐姐信息表)
- 厉害,被马赛克的图片竟然还可以恢复
- css元素旋转原点,使用transform-origin属性改变元素变换原点
- 理解BIO/NIO的基本模型
- 43 岁硅谷技术大拿命丧街头,真凶落网:熟人作案,是 Expand IT 创始人
- 一文读懂shell命令
- CentOS Stream才是未来