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权限验证相关推荐

  1. spring和maven_具有Spring和Maven教程的JAX–WS

    spring和maven Spring框架通过JAX-WS提供对Web服务的远程支持,实际上,如Spring 参考文档中所述 ,有三种将Spring POJO服务公开为JAX-WS Web服务的方式: ...

  2. 带有Spring和Maven教程的JAX–WS

    Spring框架通过JAX-WS提供对Web服务的远程支持,实际上,如Spring 参考文档中所述 ,有三种将Spring POJO服务公开为JAX-WS Web服务的方式: 公开基于Servlet的 ...

  3. [WS]使用Axis发布简单的Web服务

    使用Axis,要发布一个Web服务非常简单,简直不能再简单了,尽管看起来过程和相关代码有些长.我这个帖子里用到了这些软件:Axis 1.1.Eclipse 2.1和Eclipse的Tomcat插件2. ...

  4. 一个简单的Webservice的demo,简单模拟服务

    前段时间一直在学习WCF,匆匆忙忙的把<WCF全面解析>和<WCF服务编程>看了一遍,好多东西都不是很懂,又听了一下WCF分布式开发的网络教程,算是马马虎虎的明白点了.回顾了一 ...

  5. 简单的webService实例

    参看博文:http://nopainnogain.iteye.com/blog/791525 项目的源码与所有jar包:http://pan.baidu.com/s/1qXQuDtE 本文主要是在原来 ...

  6. 使用Axis2创建一个简单的WebService服务

    使用过Java进行过WebService开发都会听过或者接触过Apache Axis2,Axis2框架是应用最广泛的WebService框架之一了. 这里使用Axis2来开发和部署一个最简单的WebS ...

  7. 一个简单的Webservice的demo(中)_前端页面调用

    首先新建项目,这里有两种调用方式,为了能方便理解,新建页面WebserviceTest如下图: 先引用写好的服务,这里用上次写好的服务.见上次写的一个简单的Webservice的demo,简单模拟服务 ...

  8. Web Service入门简介(一个简单的WebService示例)

    一.Web Service简介 1.1.Web Service基本概念 Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intrane ...

  9. 使用 PyTorch 数据读取,JAX 框架来训练一个简单的神经网络

    使用 PyTorch 数据读取,JAX 框架来训练一个简单的神经网络 本文例程部分主要参考官方文档. JAX简介 JAX 的前身是 Autograd ,也就是说 JAX 是 Autograd 升级版本 ...

最新文章

  1. java前端目录_[Java教程]前端那点事儿——Tocify自动生成文档目录
  2. taglib遍历foreach循环list集合
  3. python基础学习[python编程从入门到实践读书笔记(连载二)]:外星人入侵项目
  4. 【quartus】原理图输入设计详解攻略
  5. XDeepFM高阶特征交互,特征交互:一种极深因子分解机模型
  6. Feign 重试解析
  7. 拓端tecdat|R语言ARMA GARCH COPULA模型拟合股票收益率时间序列和模拟可视化
  8. XLSTransformer+模板 导出 Excel
  9. FSG压缩壳和ImportREC的使用 - 脱壳篇05
  10. 如何将PayPal中的美元以人民币的形式提现到建设银行卡中?
  11. [35期] 没有硝烟的战争
  12. 音频信号处理——基音周期
  13. 微信公众平台数据统计
  14. 如果宁静是Oracle,那万茜,张雨绮,黄圣依 是什么?(附姐姐信息表)
  15. 厉害,被马赛克的图片竟然还可以恢复
  16. css元素旋转原点,使用transform-origin属性改变元素变换原点
  17. 理解BIO/NIO的基本模型
  18. 43 岁硅谷技术大拿命丧街头,真凶落网:熟人作案,是 Expand IT 创始人
  19. 一文读懂shell命令
  20. CentOS Stream才是未来

热门文章

  1. 微信小程序 长按属性
  2. java安全点_关于OopMap、SafePoint(安全点)以及安全区域
  3. python 实例对象 浅拷贝_Python3 入门教程——浅拷贝深拷贝差别
  4. js控制input框输入数字时,累计求和
  5. android中如何实现UI的实时更新---需要考虑电量和流量
  6. Git子模块引用外部项目
  7. Linux-进程、进程组、作业、会话、控制终端详解
  8. 数据结构之【树形结构】复习题
  9. jsp_servlet时序图
  10. zabbix告警时间和恢复时间相同的解决方法