Reputation: 101
What I want to do is to write a piece of code (part of bigger web-application deployed on glassfish) that connects to other system via webservice. However I'm writing client only, so I assume that I cannot change WSDL or modify anything on server side (including auth, that is probably a problem here). I'm new to webservices, so pretty please - write your answers as simple as they can be.
I was able to generate classes from WSDL, write simple command line application that connects to webservice, adds security header (add plaintext username/password, more below), calls some method and prints result. Everything works OK on command line, but if I'll attach this code to 'bigger webapp' (deploy on glassfish) I'm getting the following error:
SP0105: Either SymmetricBinding/AsymmetricBinding/TransportBinding assertion must be present in the wsdl.
I'm not getting it from there - if it works from command line (outside of glassfish), why does it need something more while deployed on glassfish?
I was using hints from this page: http://www.javadb.com/using-a-message-handler-to-alter-the-soap-header-in-a-web-service-client
To give more info on this, some pieces of code:
Code fragment for resolving endpoint and calling service (in file EndpointResolver.java):
URL baseUrl = EndpointResolver.class.getResource(".");
url = new URL(baseUrl, "WSDL_file.xml");
QName qname = new QName(SomeConfig.NAMESPACE, SomeConfig.LOCAL_PART);
Service service = Service.create(url, qname);
service.setHandlerResolver(headerHandlerResolver);
endpoint = service.getPort(MyPortType.class);
endpoint.doSomething();
//printing results here ..
HeaderHandlerResolver (implementing javax.xml.ws.handler.HandlerResolver) most important methid:
public List<Handler> getHandlerChain(PortInfo portInfo) {
List<Handler> handlerChain = new ArrayList<Handler>();
handlerChain.add(headerHandler); //injected to HeaderHandlerResolver
return handlerChain;
}
HeaderHandler handle method (auth is here :) )
public boolean handleMessage(SOAPMessageContext smc) {
Boolean outboundProperty = (Boolean) smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if ( outboundProperty.booleanValue() ) {
SOAPMessage message = smc.getMessage();
try {
SOAPEnvelope envelope = smc.getMessage().getSOAPPart().getEnvelope();
SOAPHeader header = envelope.addHeader();
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");
usernameToken.addAttribute(new QName("xmlns:wsu"), "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
SOAPElement username = usernameToken.addChildElement("Username", "wsse");
username.addTextNode("myUsername");
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("myPassword");
} catch (SOAPException e) {
log.warn(e.getMessage());
e.printStackTrace();
}
} else {
try {
//This handler does nothing with the response from the Web Service so
//we just print out the SOAP message.
logSOAPMessage(smc.getMessage());
} catch (Exception ex) {
log.warn(ex.getMessage());
ex.printStackTrace();
}
}
return outboundProperty;
}
@Override
public Set<QName> getHeaders() {
return null;
}
(...)
Thank you very much for any help with this.
edit: Below is 'policy' part from wsdl file (as stated before, I cannot change that):
<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken">
<wsp:ExactlyOne>
<wsp:All>
<sp:SupportingTokens xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:UsernameToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient"/>
</wsp:Policy>
</sp:SupportingTokens>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
Upvotes: 2
Views: 4756
Reputation: 101
I'll answer to my own question:
There were two things required to fix problem above. First thing that was required was to update metro library on glassfish (I've updated it to version 2.1.1, so updated libraries lib/webservices-rt.jar, lib/webservices-tools.jar, lib/endorsed/webservices-api.jar). That solved SP0105 error, but generated new one (ClassCastException somewhere at headers). To fix the second one, I've deleted HeaderHandler/HeaderHandlerResolver classes and instead of:
service.setHandlerResolver(headerHandlerResolver);
endpoint = service.getPort(EFormsPortType.class);
called:
endpoint = service.getPort(EFormsPortType.class);
Map<String, Object> requestContext = ((javax.xml.ws.BindingProvider) endpoint).getRequestContext();
requestContext.put(javax.xml.ws.BindingProvider.USERNAME_PROPERTY, config.getProperty("myUser");
requestContext.put(javax.xml.ws.BindingProvider.PASSWORD_PROPERTY, config.getProperty("myPassword");
Upvotes: 3