From dc9256c45ae3c08e5206b7c743939e951097dc1b Mon Sep 17 00:00:00 2001 From: Magesh Kumar B Date: Wed, 11 Feb 2015 09:59:33 +0530 Subject: [PATCH] [SWITCHYARD-2309] - Added authentication support for WSDL address --- soap/pom.xml | 8 ++ .../component/soap/OutboundHandler.java | 18 +++-- .../component/soap/util/WSDLUtil.java | 81 ++++++++++++++++++- .../component/soap/SOAPGatewayTest.java | 2 +- soap/src/test/resources/HelloWebService.wsdl | 2 +- 5 files changed, 100 insertions(+), 11 deletions(-) diff --git a/soap/pom.xml b/soap/pom.xml index cfe0d321f..3ba9993da 100644 --- a/soap/pom.xml +++ b/soap/pom.xml @@ -150,6 +150,14 @@ org.apache.ws.xmlschema xmlschema-core + + org.apache.httpcomponents + httpclient + + + org.apache.httpcomponents + httpcore + org.littleshoot littleproxy diff --git a/soap/src/main/java/org/switchyard/component/soap/OutboundHandler.java b/soap/src/main/java/org/switchyard/component/soap/OutboundHandler.java index b4ff48cd2..888b6416e 100644 --- a/soap/src/main/java/org/switchyard/component/soap/OutboundHandler.java +++ b/soap/src/main/java/org/switchyard/component/soap/OutboundHandler.java @@ -34,6 +34,7 @@ import javax.xml.ws.soap.MTOMFeature; import javax.xml.ws.soap.SOAPFaultException; +import org.apache.cxf.BusFactory; import org.apache.cxf.configuration.security.AuthorizationPolicy; import org.apache.cxf.configuration.security.ProxyAuthorizationPolicy; import org.apache.cxf.endpoint.Client; @@ -42,6 +43,7 @@ import org.apache.cxf.transport.http.HTTPConduit; import org.apache.cxf.transports.http.configuration.HTTPClientPolicy; import org.apache.cxf.transports.http.configuration.ProxyServerType; +import org.apache.cxf.wsdl.WSDLManager; import org.jboss.logging.Logger; import org.switchyard.Context; import org.switchyard.Exchange; @@ -100,14 +102,23 @@ public OutboundHandler(final SOAPBindingModel config) { protected void doStart() throws WebServiceConsumeException { if (_dispatcher == null) { try { - Definition definition = WSDLUtil.readWSDL(_config.getWsdl()); PortName portName = _config.getPort(); + URL wsdlUrl = WSDLUtil.getURL(_config.getWsdl()); + SOAPLogger.ROOT_LOGGER.creatingDispatchWithWSDL(wsdlUrl.toString()); + + Definition definition = null; + definition = WSDLUtil.readWSDL(_config.getWsdl()); javax.wsdl.Service wsdlService = WSDLUtil.getService(definition, portName); _wsdlPort = WSDLUtil.getPort(wsdlService, portName); // Update the portName portName.setServiceQName(wsdlService.getQName()); portName.setName(_wsdlPort.getName()); + // Cache the read WSDL definition + BusFactory.getThreadDefaultBus().getExtension(WSDLManager.class).addDefinition(wsdlUrl.toString(), definition); + + Service service = Service.create(wsdlUrl, portName.getServiceQName()); + String style = WSDLUtil.getStyle(_wsdlPort); _documentStyle = style.equals(WSDLUtil.DOCUMENT) ? true : false; _feature = WSDLUtil.getFeature(definition, _wsdlPort, _documentStyle); @@ -124,11 +135,6 @@ protected void doStart() throws WebServiceConsumeException { ((SOAPMessageComposer)_messageComposer).setXopExpand(_config.getMtomConfig().isXopExpand()); } - URL wsdlUrl = WSDLUtil.getURL(_config.getWsdl()); - SOAPLogger.ROOT_LOGGER.creatingDispatchWithWSDL(wsdlUrl.toString()); - - Service service = Service.create(wsdlUrl, portName.getServiceQName()); - _dispatcher = service.createDispatch(portName.getPortQName(), SOAPMessage.class, Service.Mode.MESSAGE, diff --git a/soap/src/main/java/org/switchyard/component/soap/util/WSDLUtil.java b/soap/src/main/java/org/switchyard/component/soap/util/WSDLUtil.java index 99d451d31..d65869c1c 100644 --- a/soap/src/main/java/org/switchyard/component/soap/util/WSDLUtil.java +++ b/soap/src/main/java/org/switchyard/component/soap/util/WSDLUtil.java @@ -19,6 +19,7 @@ import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; +import java.net.URLConnection; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -54,8 +55,25 @@ import javax.xml.namespace.QName; import javax.xml.transform.stream.StreamSource; +import org.apache.http.HttpHost; +import org.apache.http.HttpResponse; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.ChallengeState; +import org.apache.http.auth.Credentials; +import org.apache.http.auth.NTCredentials; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.auth.params.AuthPNames; +import org.apache.http.client.AuthCache; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.params.AuthPolicy; +import org.apache.http.client.utils.HttpClientUtils; +import org.apache.http.impl.auth.BasicScheme; +import org.apache.http.impl.client.BasicAuthCache; +import org.apache.http.impl.client.DefaultHttpClient; import org.jboss.logging.Logger; import org.switchyard.ExchangePattern; +import org.switchyard.common.codec.Base64; import org.switchyard.common.type.Classes; import org.switchyard.common.xml.XMLHelper; import org.switchyard.component.soap.SOAPMessages; @@ -139,16 +157,67 @@ private WSDLUtil() { */ public static Definition readWSDL(final String wsdlLocation) throws WSDLException { InputStream inputStream = null; + HttpClient httpclient = null; + HttpResponse response = null; try { + AuthScope authScope = null; + AuthCache authCache = null; + Credentials credentials = null; URL url = getURL(wsdlLocation); - inputStream = url.openStream(); + URL wsdlUrl = null; + httpclient = new DefaultHttpClient(); + if (url.getUserInfo() != null) { + String userInfo = url.getUserInfo(); + int idx = userInfo.indexOf("\\"); + String authString = Base64.encode(userInfo.getBytes()); + if (idx > 0) { + // NTLM + String domain = userInfo.substring(0, idx); + String rest = userInfo.substring(idx + 1, userInfo.length()); + int idx1 = rest.indexOf(":"); + String name = rest.substring(0, idx1); + String pass = rest.substring(idx1 + 1, rest.length()); + authScope = new AuthScope(url.getHost(), url.getPort(), AuthScope.ANY_REALM); + credentials = new NTCredentials(name, + pass, + "", + domain); + } else { + // BASIC + int idx1 = userInfo.indexOf(":"); + String name = userInfo.substring(0, idx1); + String pass = userInfo.substring(idx1 + 1, userInfo.length()); + authScope = new AuthScope(url.getHost(), url.getPort(), AuthScope.ANY_REALM); + credentials = new UsernamePasswordCredentials(name, pass); + // Create AuthCache instance + authCache = new BasicAuthCache(); + authCache.put(new HttpHost(authScope.getHost(), authScope.getPort()), new BasicScheme(ChallengeState.TARGET)); + } + wsdlUrl = new URL(url.getProtocol(), url.getHost(), url.getPort(), url.getFile()); + ((DefaultHttpClient)httpclient).getCredentialsProvider().setCredentials(authScope, credentials); + List authpref = new ArrayList(); + authpref.add(AuthPolicy.NTLM); + authpref.add(AuthPolicy.BASIC); + httpclient.getParams().setParameter(AuthPNames.TARGET_AUTH_PREF, authpref); + // Send a request for the Negotiation + HttpGet wsdlGet = new HttpGet(wsdlUrl.toString()); + response = httpclient.execute(wsdlGet); + // Now send the actual request + HttpClientUtils.closeQuietly(response); + response = httpclient.execute(wsdlGet); + inputStream = response.getEntity().getContent(); + } else { + wsdlUrl = url; + URLConnection urlConnection = wsdlUrl.openConnection(); + inputStream = urlConnection.getInputStream(); + } InputSource source = new InputSource(inputStream); - source.setSystemId(url.toString()); + source.setSystemId(wsdlUrl.toString()); Document wsdlDoc = XMLHelper.getDocument(source); WSDLFactory wsdlFactory = WSDLFactory.newInstance(); WSDLReader reader = wsdlFactory.newWSDLReader(); reader.setFeature("javax.wsdl.verbose", false); - return reader.readWSDL(url.toString(), wsdlDoc); + return reader.readWSDL(wsdlUrl.toString(), wsdlDoc); } catch (Exception e) { throw new WSDLException(WSDLException.OTHER_ERROR, SOAPMessages.MESSAGES.unableToReadWSDL(wsdlLocation), e); @@ -156,6 +225,12 @@ public static Definition readWSDL(final String wsdlLocation) throws WSDLExceptio if (inputStream != null) { try { inputStream.close(); + if (response != null) { + HttpClientUtils.closeQuietly(response); + } + if (httpclient != null) { + httpclient.getConnectionManager().shutdown(); + } } catch (IOException ioe) { LOGGER.error(ioe); } diff --git a/soap/src/test/java/org/switchyard/component/soap/SOAPGatewayTest.java b/soap/src/test/java/org/switchyard/component/soap/SOAPGatewayTest.java index 26dcf44e8..f89292746 100644 --- a/soap/src/test/java/org/switchyard/component/soap/SOAPGatewayTest.java +++ b/soap/src/test/java/org/switchyard/component/soap/SOAPGatewayTest.java @@ -277,7 +277,7 @@ public void invokeWithClassPathResource() throws Exception { if (rootCause != null) { // A real URL here would depend on the test environment's host and port hence, // it is sufficient to test that we actually loaded the WSDL from classpath - Assert.assertEquals("javax.xml.ws.WebServiceException: Unsupported endpoint address: REPLACE_WITH_ACTUAL_URL", rootCause); + Assert.assertEquals("java.net.UnknownHostException: REPLACE_WITH_ACTUAL_URL", rootCause); } } diff --git a/soap/src/test/resources/HelloWebService.wsdl b/soap/src/test/resources/HelloWebService.wsdl index 19d44d9ce..0a2599d8e 100644 --- a/soap/src/test/resources/HelloWebService.wsdl +++ b/soap/src/test/resources/HelloWebService.wsdl @@ -66,7 +66,7 @@ - +