1 Set up trasparent echoing proxy ( or logging proxy)
2 Create a ProxySelector
package com.lois.contentmanagement.sharepoint.external;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.ProxySelector;
import java.net.SocketAddress;
import java.net.URI;
import java.net.Proxy.Type;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import com.lois.contentmanagement.sharepoint.ConfigDelegate;
/**
- <p>
- To talk to sharepoint we need to authenticate, easiest way for us to
- authenticate is to use NTLM, (Microsoft network auth protocol)
- Easiest way to use NTLM is to use a proxy, see http://ntlmaps.sourceforge.net/.
- <p>
- This class enroles a ProxySelector that selects our ntlm proxy for any connections
- to our sharePointHost.
- <p>
- To ensure this is registered call ensureInitilised().
- @author dwaters
*/
public class NTLMProxySelector extends ProxySelector {
private static final Logger logger = Logger.getLogger(NTLMProxySelector.class);
private static boolean initialised = false;
private final String sharePointHost;
private final Proxy ntlmProxy;
private final ProxySelector existingSelector;
private NTLMProxySelector(ProxySelector existingSelector, String sharePointHost, Proxy ntlmProxy)
{
super();
this.existingSelector = existingSelector;
this.sharePointHost = sharePointHost;
this.ntlmProxy = ntlmProxy;
}
public static void ensureInitilised(){
if(initialised) return; // If initialised return, don't lock in the majority case of already initialised
synchronized (NTLMProxySelector.class)
{ // Lock class
if(initialised) return; // Check we where not initialised while waiting for lock.
// Get Config Settings
String sharePointHost = ConfigDelegate.getString("ContentManager.SharePoint.SharePointHost");
String ntlmProxyHost = ConfigDelegate.getString("ContentManager.SharePoint.Proxy.Host");
int ntlmProxyPort = Integer.parseInt(ConfigDelegate.getString("ContentManager.SharePoint.Proxy.Port"));
SocketAddress addr = new InetSocketAddress(ntlmProxyHost,ntlmProxyPort);
// construct referenc to proxy.
Proxy ntlmProxy = new Proxy(Type.HTTP,addr);
// create our instance of ProxySelector passing in any already defined
ProxySelector selector = new NTLMProxySelector(ProxySelector.getDefault(), sharePointHost, ntlmProxy);
ProxySelector.setDefault(selector); // set us as the default proxySelector
initialised = true;
}
}
@Override
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
/*
- We are not interested in this event, if we have a parent proxySelector
- pass the event onto them
*/
if(existingSelector != null)
{
existingSelector.connectFailed(uri, sa, ioe);
}
}
@Override
public List<Proxy> select(URI uri) {
if(logger.isDebugEnabled())
{
logger.debug("NTLMProxySelector Called for " + uri.toString());
}
// if this request is for our sharePointHost
if(uri.getHost().equalsIgnoreCase(sharePointHost))
{
logger.debug("Using our proxy.");
List<Proxy> ret = new ArrayList<Proxy>(1);
ret.add(ntlmProxy); // return our proxy only;
return ret;
}
else if(existingSelector != null)
{ // else if we replaced an existing proxySelectory ask them
return existingSelector.select(uri);
}
else
{ // else no proxy
List<Proxy> ret = new ArrayList<Proxy>();
ret.add(Proxy.NO_PROXY);
return ret;
}
}
}
3 create JAX-WS client class for a known good webservice using java 1.6 wsimport or jboss wsconsume.bat
4 And assign this ProxySelector to be the default (if using the code above, call ensureInitilised)
5 Call the WebSevice
NTLMProxySelector.ensureInitilised();
...
ChunkedEncodingFeature chunkedEncodingFeature = new ChunkedEncodingFeature(false);
Repository repo = new Repository(sharePointUrl, qname);
RepositorySoap repoSoap = repo.getPort(RepositorySoap.class, chunkedEncodingFeature);
...
FileInformation upload = repoSoap.upload(userCompanyId, fileName, arrayOfMeta, document);
6 Check the proxy log, I see a request for the WSDL but the call to the webservice itsself goes direct and does not use the configured proxy.