`

Java 调用Web service 添加认证头(soapenv:Header)

 
阅读更多
 
 

前言

有时候调用web service 会出现

Message does not conform to configured policy [ AuthenticationTokenPolicy(S) ]:  No Security Header found 

这样的错误。

以在 soapui 调用的结果来看, 会出现如下的返回

出现这种错误的原因 是webservice 的服务端需要提供 soap 认证的表头。

举例来说, 可能需要加上如下的认证头:

 

[html] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. <soapenv:Header>  
  2.   <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1">  
  3.     <wsse:UsernameToken>  
  4.       <wsse:Username>UserName</wsse:Username>  
  5.       <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">Password</wsse:Password>  
  6.     </wsse:UsernameToken>  
  7.   </wsse:Security>  
  8. </soapenv:Header>  
(这个细部的格式和服务端的要求有关, 具体的username和pass也是服务端提供的)

在sopaui 调用的时候, 加上类似, 就能呼叫成功了。

 

 

在soapui 调用, 可以用以上方式来做。在把wsdl 转为java 后, 又该如何加上认证的头信息呢?

 

cxf 加上认证头

(以上的认证头, 比较接近cxf 的调用方式。)

如果使用的是cxf生产的客户端的代码。

(如何生成,参考 CXF 生成Web Service Client(将WSDl 转化成 Java代码)

在 _Client 调用的时候加上 如下代码:(在方法调用的代码之前)

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. Map<String, Object> props = new HashMap<String, Object>();  
  2. props.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);        
  3. props.put(WSHandlerConstants.PASSWORD_TYPE,WSConstants.PW_TEXT);  
  4. props.put(WSHandlerConstants.USER, "UserName");  
  5. props.put(WSHandlerConstants.PW_CALLBACK_CLASS, PasswordHandler.class.getName());  
  6. WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(props);  
  7. Client client = ClientProxy.getClient(port);  
  8. client.getOutInterceptors().add(wssOut);  

在client 的java 文件中, 新增以下内部类

 

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. public static class PasswordHandler implements CallbackHandler  
  2. {  
  3.     public void handle(javax.security.auth.callback.Callback[] callbacks) {  
  4.         for (int i = 0; i < callbacks.length; i++) {  
  5.             WSPasswordCallback pc = (WSPasswordCallback)callbacks[i];  
  6.             pc.setPassword("password");  
  7.         }  
  8.     }  
  9.   
  10. }  


 

Axis2 加上认证头

针对以上的认证头在axis2 产生的java 文件中如何添加呢(Axis2自动产生的java 文件并不会自动产生main的测试文件, 需要自己写。  XXXXProxy.java 这是供调用的类文件。 不过这些和添加认证头关系不大)

axis2会产生一个  XXXXPortBindingStub.java 的文件。 这里面的内容就是实际的方法体。

找到我们需要调用的那个方法体:

在方法调用之前,加入以下代码:

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. //Begin add for Header  
  2.         String AUTH_PREFIX = "wsse";  
  3.         String AUTH_NS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";  
  4.          try{  
  5.             SOAPElement wsSecHeaderElm = soapFactory.createElement("Security", AUTH_PREFIX, AUTH_NS);          
  6.             SOAPElement userNameTokenElm = soapFactory.createElement("UsernameToken",AUTH_PREFIX, AUTH_NS);            
  7.             SOAPElement userNameElm = soapFactory.createElement("Username",AUTH_PREFIX, AUTH_NS);           
  8.             SOAPElement passwdElm = soapFactory.createElement("Password",AUTH_PREFIX, AUTH_NS);                   
  9.             passwdElm.setAttribute("Type""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");  
  10.             
  11.        userNameElm.addTextNode("vend_bmc01");  
  12.        passwdElm.addTextNode("mediatek");  
  13.               
  14.       userNameTokenElm.addChildElement(userNameElm);  
  15.       userNameTokenElm.addChildElement(passwdElm);  
  16.       wsSecHeaderElm.addChildElement(userNameTokenElm);           
  17.       SOAPHeaderElement soapHeaderElement =  new SOAPHeaderElement(wsSecHeaderElm);  
  18.       soapHeaderElement.setMustUnderstand(true);  
  19.       _call.addHeader(soapHeaderElement);    
  20.         }catch(Exception e)  
  21.         {  
  22.             e.printStackTrace();  
  23.         }          
  24.       //End add for Header  
  25.    
  26. ===》call method  
  27.        java.lang.Object _resp = _call.invoke(XXXX);  

原理很简单。 加上类似xml 的头, _call_addHeader

 

加上之后,再触发方法 _call.invoke

分享到:
评论

相关推荐

    webservice启动没有问题,通过自动生成的客户端报错

    faultString: java.lang.reflect.InvocationTargetException faultActor: faultNode: faultDetail: {http://xml.apache.org/axis/}stackTrace: AxisFault faultCode: {...

    C#调用和实现WebService,纯手工打造!

    因为对方用的C++实现,添加Web服务引用方式无效……直接添加WSDL的调用对方不认…… 只好手工打造,还好C#足够强大。 HttpWebRequest类可以简单的实现WebService调用。   首先手工打造SOAP包内容 代码如下:string...

    spring-boot-webservice:弹簧启动Web服务

    弹簧启动Web服务弹簧启动Web服务测试请求: 标头: 内容类型:text / xml &lt; soapenv xss=removed xss=removed&gt; &lt; soapenv&gt; &lt; soapenv&gt; &lt; gs&gt; &lt; gs&gt;Spain&lt;/ gs&gt; &lt;/ gs&gt; &lt;/ soapenv&gt;&lt;/ soapenv : Env

    SOAP 协议 规范

    SOAP以XML形式提供了一个简单、轻量的用于在分散或分布环境中交换结构化和类型信息的机制。SOAP本身并没有定义任何应用程序语义,如编程模型或特定语义的实现;实际上它通过提供一个有标准组件的包模型和在模块中...

    soap1.1和soap1.2区别

    POST /WSShakespeare.asmx HTTP/1.1 SOAP 1.1 request: 报头和 xmlns:soap12不一样

    spring-boot-webservice2:弹簧启动webservice2

    弹簧启动webservice2 弹簧启动webservice2 ...&lt; soapenv xss=removed xss=removed&gt; &lt; soapenv&gt; &lt; soapenv&gt; &lt; userId&gt;411001 &lt;/ soapenv&gt; &lt;/ soapenv&gt; 响应: &lt; soap : Envelope xmln

    ws-demo:简单的SOAP服务器

    ws-demo 简单的SOAP服务器WSDL模型: H2数据库控制台:端点: XML createCountryRequest示例: &lt; soapenv xss=removed xss=removed&gt; &lt; soapenv&gt; &lt; soapenv&gt; &lt; gs&gt; &lt; gs&gt; &lt; gs&gt;Russia&lt;/ gs&gt; &lt; gs : pop

    Heisln-currency-converter

    salamibrot运行容器docker-compose up --build -d提供的SOAP操作端点: : : WSDL: : : 运作方式: /convertCurrency convert a single value/convertCurrencies convert an array of values范例要求&lt; soapenv xss=...

Global site tag (gtag.js) - Google Analytics