After many painful hours of trying various things I finally have the answer.
The following is the only way I could get proxy authentication working via aweb service using jboss 5.1.0.GA.
First upgrade your jbossws to jbossws-cxf-3.3.1.GA(latest version as of writing) from (http://www.jboss.org/jbossws/downloads.html). It's a simple task make sure you have apache ant installed as you will need it to install this update into jboss.
To upgrage download and unpack the zip file
Follow the instuctions in the doc folder, basically it's set the home folder of your jboss app in the ant.properties file and run ant deploy-jboss510
You should be able to run ant test to test your installation (Don't forget to start your server first).
Now jboss should be in good shape to handle proxies for web service clients
You will need to create a proxySelector
Register the proxySelector
Add some proxy-Authentication to the header of the web service request and your done.
Here's an example proxy selector. This has been taken from the JDK5 documetation. Change the proxy address to yours.
package com.fugrodata.bgwebservices.session;
import java.net.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.io.IOException;
public class MyProxySelector extends ProxySelector {
// Keep a reference on the previous default
ProxySelector defsel = null;
/*
* Inner class representing a Proxy and a few extra data
*/
class InnerProxy {
Proxy proxy;
SocketAddress addr;
// How many times did we fail to reach this proxy?
int failedCount = 0;
InnerProxy(InetSocketAddress a) {
addr = a;
proxy = new Proxy(Proxy.Type.HTTP, a);
}
SocketAddress address() {
return addr;
}
Proxy toProxy() {
return proxy;
}
int failed() {
return ++failedCount;
}
}
/*
* A list of proxies, indexed by their address.
*/
HashMap<SocketAddress, InnerProxy> proxies = new HashMap<SocketAddress, InnerProxy>();
MyProxySelector(ProxySelector def) {
// Save the previous default
defsel = def;
// Populate the HashMap (List of proxies)
InnerProxy i = new InnerProxy(new InetSocketAddress("proxy", 8080));
proxies.put(i.address(), i);
//i = new InnerProxy(new InetSocketAddress("webcache2.mydomain.com", 8080));
//proxies.put(i.address(), i);
//i = new InnerProxy(new InetSocketAddress("webcache3.mydomain.com", 8080));
//proxies.put(i.address(), i);
}
/*
* This is the method that the handlers will call.
* Returns a List of proxy.
*/
public java.util.List<Proxy> select(URI uri) {
// Let's stick to the specs.
if (uri == null) {
throw new IllegalArgumentException("URI can't be null.");
}
/*
* If it's a http (or https) URL, then we use our own
* list.
*/
String protocol = uri.getScheme();
if ("http".equalsIgnoreCase(protocol) ||
"https".equalsIgnoreCase(protocol)) {
ArrayList<Proxy> l = new ArrayList<Proxy>();
for (InnerProxy p : proxies.values()) {
l.add(p.toProxy());
}
return l;
}
/*
* Not HTTP or HTTPS (could be SOCKS or FTP)
* defer to the default selector.
*/
if (defsel != null) {
return defsel.select(uri);
} else {
ArrayList<Proxy> l = new ArrayList<Proxy>();
l.add(Proxy.NO_PROXY);
return l;
}
}
/*
* Method called by the handlers when it failed to connect
* to one of the proxies returned by select().
*/
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
// Let's stick to the specs again.
if (uri == null || sa == null || ioe == null) {
throw new IllegalArgumentException("Arguments can't be null.");
}
/*
* Let's lookup for the proxy
*/
InnerProxy p = proxies.get(sa);
if (p != null) {
/*
* It's one of ours, if it failed more than 3 times
* let's remove it from the list.
*/
if (p.failed() >= 3)
proxies.remove(sa);
} else {
/*
* Not one of ours, let's delegate to the default.
*/
if (defsel != null)
defsel.connectFailed(uri, sa, ioe);
}
}
}
Register the proxy above using this code
MyProxySelector ps = new MyProxySelector(ProxySelector.getDefault());
ProxySelector.setDefault(ps);
Your jvm will start to use the proxy selector from this point forward. Now to add the authentication for the webservice request to authenticate against the proxy. The Proxy-Authorization header is added manually to the web service request. This is done on the webservice classes, here's an example.
Service service = new Service();
ServiceOperations portType = service.getService();
Map<String, List<String>> map2 = (Map<String, List<String>>) ((BindingProvider) portType).getRequestContext().get(MessageContext.HTTP_REQUEST_HEADERS);
Map<String, List<String>> map = map2;
if (map == null)
map = new HashMap<String, List<String>>();
map.put("Proxy-Authorization", Collections.singletonList(
"Basic " + Base64.encodeBytes(("username:password").getBytes())));
System.out.println("Adding to HttpRequestHeaders [map="+map+"] ...");
((BindingProvider) portType).getRequestContext().put(MessageContext.HTTP_REQUEST_HEADERS, map);
/// portType.webserviceMethod(...);
Change the username and password to suit your proxy in the code above.
Job done!