使用 SOAP 与 JAX-WS 和 WS-Addressing



我已经使用 wsimport 创建了一些 JAX-WS 工件。这是我使用的 wsimport 命令。

wsimport -b "C:tempCustomization.xml" -B-XautoNameResolution -d C:temp -extension -J-Djavax.xml.accessExternalSchema=all -J-Djavax.xml.accessExternalDTD=all -keep -verbose -XadditionalHeaders -Xnocompile https://api.sendwordnow.com/webservices/v3/users.svc?wsdl

这似乎奏效了。至少我认为是这样。WSIMPORT创建了许多软件包,甚至创建了一个公共接口。现在,这是我如何尝试连接到我认为有效的端点的代码截图。

HttpTransportPipe.dump = true;
Users users = new Users();
IUsers iUsers = users.getWSHttpBindingIUsers();
((BindingProvider)iUsers).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://api.sendwordnow.com/webservices/v3/Users.svc");
((BindingProvider)iUsers).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "somename");
((BindingProvider)iUsers).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "somepassword");
iUsers.echoAuthenticated("This is an echo test.");
System.out.println();

我尝试了不同的方法来设置用户名和密码,但我总是收到HTTP传输错误:java.net.ConnectException:连接超时:连接。我跳到了 SoapUI 上,并从 https://api.sendwordnow.com/webservices/v3/users.svc?wsdl 年用 WSDL 创建了一个新项目。我可以向 https://api.sendwordnow.com/webservices/v3/Users.svc 提交请求,并且通过正确的身份验证和将 WSS 密码类型属性设置为"密码文本",我可以成功调用 EchoAuthenticated。这是 SoapUI 的输出。

Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "POST /webservices/v3/Users.svc HTTP/1.1[r][n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "Accept-Encoding: gzip,deflate[r][n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "Content-Type: application/soap+xml;charset=UTF-8;action="http://www.sendwordnow.com/contract/users/v3/IUsers/EchoAuthenticated"[r][n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "Authorization: Basic c2lyaXVzYXBpOnRlbXBvcmFyeTEyMw==[r][n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "Content-Length: 1224[r][n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "Host: api.sendwordnow.com[r][n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "Connection: Keep-Alive[r][n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "User-Agent: Apache-HttpClient/4.1.1 (java 1.5)[r][n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "[r][n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:v3="http://www.sendwordnow.com/contract/users/v3">[n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "   <soap:Header xmlns:wsa="http://www.w3.org/2005/08/addressing"><wsse:Security soap:mustUnderstand="true" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><wsse:UsernameToken wsu:Id="UsernameToken-838F7D896DB9148E2414907229483491"><wsse:Username>somename</wsse:Username><wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">somepassword</wsse:Password><wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">QpJwiZjZex+3ikqVWZp+Yw==</wsse:Nonce><wsu:Created>2017-03-28T17:42:28.348Z</wsu:Created></wsse:UsernameToken></wsse:Security><wsa:Action>http://www.sendwordnow.com/contract/users/v3/IUsers/EchoAuthenticated</wsa:Action></soap:Header>[n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "   <soap:Body>[n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "      <v3:EchoAuthenticated>[n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "         <!--Optional:-->[n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "         <v3:value>This is an echo test.</v3:value>[n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "      </v3:EchoAuthenticated>[n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "   </soap:Body>[n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "</soap:Envelope>"
Tue Mar 28 12:42:29 CDT 2017:DEBUG:<< "HTTP/1.1 200 OK[r][n]"
Tue Mar 28 12:42:29 CDT 2017:DEBUG:<< "Content-Type: application/soap+xml; charset=utf-8[r][n]"
Tue Mar 28 12:42:29 CDT 2017:DEBUG:<< "Server: Microsoft-IIS/8.5[r][n]"
Tue Mar 28 12:42:29 CDT 2017:DEBUG:<< "Date: Tue, 28 Mar 2017 17:42:29 GMT[r][n]"
Tue Mar 28 12:42:29 CDT 2017:DEBUG:<< "Content-Length: 887[r][n]"
Tue Mar 28 12:42:29 CDT 2017:DEBUG:<< "[r][n]"
Tue Mar 28 12:42:29 CDT 2017:DEBUG:<< "<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><s:Header><a:Action s:mustUnderstand="1">http://www.sendwordnow.com/contract/users/v3/IUsers/EchoAuthenticatedResponse</a:Action><o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><u:Timestamp u:Id="_0"><u:Created>2017-03-28T17:42:29.695Z</u:Created><u:Expires>2017-03-28T17:47:29.695Z</u:Expires></u:Timestamp></o:Security></s:Header><s:Body><EchoAuthenticatedResponse xmlns="http://www.sendwordnow.com/contract/users/v3"><EchoAuthenticatedResult>This is the Users service answering back. The value you sent was: This is an echo test.</EchoAuthenticatedResult></EchoAuthenticatedResponse></s:Body></s:Envelope>"

看起来我缺少wsa:Action,wsse:password Type和wsse:Nonce EncodingType。至少这是 SoapUI 请求中的内容。我觉得我做错了。我显然需要那些缺少的组件,但我似乎无法弄清楚如何实际实现它们。任何建议都会非常有帮助。我以为我会收到一些身份验证错误,但我似乎甚至无法走那么远。

更新 1

我不确定我是否更接近这一点。这是 SoapUI 请求。

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:v3="http://www.sendwordnow.com/contract/users/v3">
<soap:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
<wsse:Security soap:mustUnderstand="true" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-1" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>
*********</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">
**********</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">
zhVqVXnkOsPCFRZolLSWtw==</wsse:Nonce>
<wsu:Created>
2017-03-29T14:05:54.820Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
<wsa:Action>
http://www.sendwordnow.com/contract/users/v3/IUsers/EchoAuthenticated
</wsa:Action>
</soap:Header>
<soap:Body>
<v3:EchoAuthenticated>
<v3:value>
Test Message</v3:value>
</v3:EchoAuthenticated>
</soap:Body>
</soap:Envelope>

这是一个代码截图。

SOAPElement security = header.addChildElement("Security", "wsse",
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
SOAPElement userToken = security.addChildElement("UsernameToken", "wsse");
userToken.addChildElement("Username", "wsse").addTextNode("someusername");
userToken.addChildElement("Password", "wsse").addTextNode("somepassword");
userToken.addChildElement("Nonce", "wsse").addTextNode("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
userToken.addChildElement("Password", "wsse").addTextNode("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
userToken.addChildElement("Action", "wsa");

我不再超时,但现在收到此错误。

com.sun.xml.internal.ws.streaming.XMLStreamReaderException: unexpected XML tag. expected: {http://www.sendwordnow.com/contract/users/v3}EchoAuthenticatedResponse but found: {http://www.sendwordnow.com/contract/users/v3}EchoAuthenticated

我是否需要将 wsa:action 设置为特定 URL?

虽然这不是唯一的一块,但它是拼图的一个主要部分。

security.addAttribute(soapFactory.createName("S:mustUnderstand"),"1");

我一直在使用这个。

security.addAttribute(soapFactory.createName("SOAP:mustUnderstand"),"True");

在构建WSSE和WSA元素树时进行了其他一些更改,但这确实引起了我的悲伤。现在一切都很好。

最新更新