我正在尝试使用Java连接(没有成功)到以下WS:
我尝试使用soapui但没有成功。尝试过Basic和NTLM身份验证,我总是收到以下错误:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="1">http://www.w3.org/2005/08/addressing/soap/fault</a:Action>
</s:Header>
<s:Body>
<s:Fault>
<faultcode xmlns:a="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">a:InvalidSecurity</faultcode>
<faultstring xml:lang="en-US">An error occurred when verifying security for the message.</faultstring>
</s:Fault>
</s:Body>
</s:Envelope>
此Web服务的官方说明显示以下使用C#进行连接的示例。我没有测试过这个,但我认为它可以正常工作。
try {
var proxy = new ChannelFactory<ServiceReferenceWCF.ITerytWs1>("custom");
proxy.Credentials.UserName.UserName = login;
proxy.Credentials.UserName.Password = haslo;
var result = proxy.CreateChannel();
var test = result.CzyZalogowany(); // should return true if connected correctly
} catch (Exception ex) { }
以下设置:
<client>
<endpoint address="https://uslugaterytws1.stat.gov.pl/TerytWs1.svc" binding="customBinding" bindingConfiguration="custom" contract="ServiceReference1.ITerytWs1" name="custom" />
</client>
<bindings>
<customBinding>
<binding name="custom">
<security defaultAlgorithmSuite="Default" authenticationMode="UserNameOverTransport" requireDerivedKeys="true" includeTimestamp="true" messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10">
<localClientSettings detectReplays="false" />
<localServiceSettings detectReplays="false" />
</security>
<textMessageEncoding messageVersion="Soap11WSAddressing10" />
<httpsTransport maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647" />
</binding>
</customBinding>
</bindings>
所以我尝试使用Java以下方式连接:
public static void main(String[] args) {
try {
final String wsdlResourcePath = "wsdl/jaxb/teryt/terytws1.wsdl";
final String url = "https://uslugaterytws1test.stat.gov.pl/TerytWs1.svc";
ITerytWs1 teryt = createSoapEndpoint((wsdlLocation) -> new TerytWs1(wsdlLocation).getCustom(), wsdlResourcePath, url);
System.out.println(teryt.czyZalogowany());
} catch (Exception e) { }
}
private static <SOAP> SOAP createSoapEndpoint(SoapCreator<SOAP> soapCreator, String wsdlResourcePath, String url) {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
URL wsdlLocation = cl.getResource(wsdlResourcePath);
SOAP soap = soapCreator.create(wsdlLocation);
BindingProvider provider = (BindingProvider) soap;
Map<String, Object> context = provider.getRequestContext();
context.put(BindingProvider.USERNAME_PROPERTY, "TestPubliczny");
context.put(BindingProvider.PASSWORD_PROPERTY, "1234abcd");
context.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, url);
return soap;
}
不幸的是,代码在调用期间冻结了#ter; teryt.czyZalogowany()&#34;。没有超时 - 任何事情,只是永远处理这条线,或者被阻止。
我的Java代码会生成以下警告消息:
警告:WSP0075:策略断言 &#34; {http://schemas.xmlsoap.org/ws/2005/07/securitypolicy} SignedSupportingTokens&#34; 被评估为&#34; UNKNOWN&#34;。 lip 27,2017 11:58:35 AM [com.sun.xml.internal.ws.policy.EffectiveAlternativeSelector] selectAlternatives警告:WSP0075:策略断言 &#34; {http://schemas.xmlsoap.org/ws/2005/07/securitypolicy} TransportBinding&#34; 被评估为&#34; UNKNOWN&#34;。 lip 27,2017 11:58:35 AM [com.sun.xml.internal.ws.policy.EffectiveAlternativeSelector] selectAlternatives警告:WSP0075:策略断言 &#34; {http://schemas.xmlsoap.org/ws/2005/07/securitypolicy} Trust10&#34;是 评估为&#34; UNKNOWN&#34;。 lip 27,2017 11:58:35 AM [com.sun.xml.internal.ws.policy.EffectiveAlternativeSelector] selectAlternatives警告:WSP0075:策略断言 &#34; {http://schemas.xmlsoap.org/ws/2005/07/securitypolicy} WSS11&#34;是 评估为&#34; UNKNOWN&#34;。 lip 27,2017 11:58:35 AM [com.sun.xml.internal.ws.policy.EffectiveAlternativeSelector] selectAlternatives警告:WSP0075:策略断言 &#34; {http://www.w3.org/2006/05/addressing/wsdl} UsingAddressing&#34;是 评估为&#34; UNKNOWN&#34;。 lip 27,2017 11:58:35 AM [com.sun.xml.internal.ws.policy.EffectiveAlternativeSelector] selectAlternatives警告:WSP0019:次优的策略替代方案 在客户端选择健身&#34; UNKNOWN&#34;。
也许有人对此类问题了解得更多,或者能够通过他自己的配置直接连接到这个WS - 目前我还没有一个线索可能是什么问题,而我看到&#34;浪费时间&#34;在我面前的视角......所以请帮助。
答案 0 :(得分:2)
请启用寻址功能:
TerytWs1 teryt = new TerytWs1();
//teryt.setHandlerResolver(new HeaderHandlerResolver());
WebServiceFeature wsAddressing = new AddressingFeature(true);
ITerytWs1 client = teryt.getCustom(wsAddressing);
答案 1 :(得分:0)
我设法使用JAX-WS连接到TERYT。
首先,您需要使用wsimport为客户端生成类。在生成的类中,将有ITerytWs1和TerytWs1 - 它们是您此时唯一感兴趣的类。 然后,您可以添加SOAPHandler类来处理标题,如下所示:
public class TerytHeaderHandler implements SOAPHandler<SOAPMessageContext>
{
private String wsUser;
private String wsPassword;
public TerytHeaderHandler(String wsUser, String wsPassord)
{
this.wsUser = wsUser;
this.wsPassword = wsPassord;
}
@Override
public boolean handleMessage(SOAPMessageContext smc)
{
Boolean outboundProperty = (Boolean) smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outboundProperty.booleanValue())
{
try
{
SOAPEnvelope envelope = smc.getMessage().getSOAPPart().getEnvelope();
SOAPHeader header = envelope.getHeader();
SOAPElement security = header.addChildElement("Security", "wsse",
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
SOAPElement usernameToken = security.addChildElement("UsernameToken", "wsse");
SOAPElement username = usernameToken.addChildElement("Username", "wsse");
username.addTextNode(wsUser);
SOAPElement password = usernameToken.addChildElement("Password", "wsse");
password.setAttribute("Type",
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
password.addTextNode(wsPassword);
} catch (Exception e)
{
e.printStackTrace();
}
} else
{
//This handler does nothing with the response from the Web Service
//even though it should probably check its mustUnderstand headers
SOAPMessage message = smc.getMessage();
}
return outboundProperty;
}
@Override
public boolean handleFault(SOAPMessageContext context)
{
// TODO Auto-generated method stub
return false;
}
@Override
public void close(MessageContext context)
{
// TODO Auto-generated method stub
}
// Gets the header blocks that can be processed by this Handler instance.
@Override
public Set<QName> getHeaders()
{
QName securityHeader = new QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
"Security");
HashSet<QName> headers = new HashSet<QName>();
headers.add(securityHeader);
return headers;
}
}
然后你就像这样使用它:
public class Main {
public static void main(String[] args) {
ITerytWs1 instance = new TerytWs1().getCustom(new AddressingFeature(true));
Binding binding = ((BindingProvider) instance).getBinding();
List<Handler> handlerList = binding.getHandlerChain();
if (handlerList == null)
handlerList = new ArrayList<Handler>();
handlerList.add(new TerytHeaderHandler("TestPubliczny", "1234abcd"));
binding.setHandlerChain(handlerList);
System.out.println(instance.czyZalogowany());
}
}
就我而言,我遇到了getHeaders()函数的问题。由于StackOverflow上有关于其他问题的建议,可以管理它。