开发者

Proxy access from JBoss

开发者 https://www.devze.com 2023-03-31 19:57 出处:网络
We have an app running on JBoss. In many installations the serv开发者_JS百科er is running behind a firewall that denies it access to the internet except through a proxy.

We have an app running on JBoss. In many installations the serv开发者_JS百科er is running behind a firewall that denies it access to the internet except through a proxy. Now my task is to find out how to use this proxy when authentication is necessary.

Configuring JBoss to use a proxy is no problem with -Dhttp.proxyHost=proxy_host -Dhttp.proxyPort=proxy_port, but I see no way to indicate the username and password.

On a non-EJB-app I have had success using Authenticator.setDefault(new ProxyAuthenticator("test", "test")) where ProxyAuthenticator is extending Authenticator. This, however, does not work on JBoss.

A sub-problem I have to this case is that the server and the non-EJB-app needs to have access to local resources without using the proxy.


You can stop the app from using the proxy for certain hosts with the following property:

-Dhttp.nonProxyHosts="*.foo.com|localhost"

As for authenticating against a proxy, you may find this and this useful.


Finally I got this this to work. With the two links in Richs post and some trial and error it now works as requiered. At the moment I have only implemented basic authentication and I will have to add other authentication types in the future.

A big obstruction was that I started configuring the JVM with -Dhttp.proxyHost and -Dhttp.proxyPort. That somehow confused the JVM more than it helped. With that configuration the ProxyAuthenticator.getPasswordAuthentication() was never called. So it is necessary also to set a default ProxySelector.

The code leads everything through the proxy - also calls to local addresses. Soon I'll need to work on a solution to this :-) (Any ideas?)

This is what I do to set it up:

ProxySelector proxySelector;
if (proxySelector == null) {
    proxySelector = new MyProxySelector(ProxySelector.getDefault(), address, port);
}

ProxySelector.setDefault(proxySelector);
Authenticator.setDefault(ProxyAuthenticator.getInstance());

MyProxySelector:

import java.io.IOException;
import java.net.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class MyProxySelector extends ProxySelector {
    /**
     * Keep a reference on the default ProxySelector
     */
    private ProxySelector defaultProxySelector = null;
    private static ProxySelector proxySelector;

    /*
     * Inner class representing a Proxy and a few extra data
     */
    private 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. */
    private HashMap<SocketAddress, InnerProxy> proxies = new HashMap<SocketAddress, InnerProxy>();

    public MyProxySelector(ProxySelector def, String address, Integer port) {
        // Save the previous default
        defaultProxySelector = def;

        // Populate the HashMap (List of proxies)
        InnerProxy i;
        if (address != null && port != null) {
            i = new InnerProxy(new InetSocketAddress(address, port));
            proxies.put(i.address(), i);
        }
    }

    /**
     * This is the method that the handlers will call.
     *
     * @param uri
     * @return a List of proxies.
     */
    public List<Proxy> select(URI uri) {
        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)) {
            List<Proxy> proxyList = new ArrayList<Proxy>();
            for (InnerProxy p : proxies.values()) {
                proxyList.add(p.toProxy());
            }

            if (proxyList.size() == 0) {
                proxyList.add(Proxy.NO_PROXY);
            }
            return proxyList;
        }

         // Not HTTP or HTTPS (could be SOCKS or FTP)
         // defer to the default selector.
        if (defaultProxySelector != null) {
            return defaultProxySelector.select(uri);
        } else {
            List<Proxy> proxyList = new ArrayList<Proxy>();
            proxyList.add(Proxy.NO_PROXY);
            return proxyList;
        }
    }

    /**
     * Method called by the handlers when it failed to connect
     * to one of the proxies returned by select().
     *
     * @param uri
     * @param sa
     * @param ioe
     */
    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 (defaultProxySelector != null)
                defaultProxySelector.connectFailed(uri, sa, ioe);
        }
    }
}

ProxyAuthenticator:

import org.bouncycastle.crypto.RuntimeCryptoException;

import java.net.Authenticator;
import java.net.PasswordAuthentication;

public class ProxyAuthenticator extends Authenticator {

    private String user;
    private String password;
    private static ProxyAuthenticator authenticator;

    public ProxyAuthenticator(String user, String password) {
        this.user = user;
        this.password = password;
    }

    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication(user, password.toCharArray());
    }

    public static Authenticator getInstance(String user, String password) {
        if (authenticator == null) {
            authenticator = new ProxyAuthenticator(user, password);
        }
        return authenticator;
    }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消