2011-08-31 38 views
2

我們有一個在JBoss上運行的應用程序。在許多安裝中,服務器運行在防火牆之後,除了通過代理之外,它拒絕訪問互聯網。 現在我的任務是瞭解如何在需要身份驗證時使用此代理。來自JBoss的代理訪問

配置JBoss使用代理與-Dhttp.proxyHost=proxy_host -Dhttp.proxyPort=proxy_port沒有問題,但我看不出用戶名和密碼。

在非EJB應用程序上,我已成功使用Authenticator.setDefault(new ProxyAuthenticator("test", "test")),其中ProxyAuthenticator正在擴展身份驗證器。但是,這在JBoss上不起作用。

我必須面對這種情況的一個子問題是服務器和非EJB應用程序需要訪問本地資源而不使用代理。

回答

1

最後我得到了這個工作。通過裏奇郵政的兩個鏈接和一些試驗和錯誤,它現在按要求工作。 目前我只實現了基本身份驗證,我將來還需要添加其他身份驗證類型。

一個很大的障礙是我開始使用-Dhttp.proxyHost and -Dhttp.proxyPort配置JVM。這讓JVM感到困惑不止。使用該配置,ProxyAuthenticator.getPasswordAuthentication()從未被調用過。所以還需要設置一個默認的ProxySelector。

代碼通過代理引導一切 - 也調用本地地址。不久,我需要一個解決這個:-)工作

這是我做的設置它(任何想法?):

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; 
    } 
} 
1

您可以使用代理與下列財產某些主機停止應用程序:

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

至於對認證代理,你會發現thisthis有用。

+0

第一個鏈接預設爲您正在運行JBoss 5.1.0 GA和JBossWS 3.3.1。我們正在運行4.3.0 GA :-( 第二個鏈接只使用了Authenticator.setDefault,我已經嘗試過了 – homaxto

+0

你能解釋這種方法不起作用嗎?我能想到的唯一的其他解決方案是對已關閉的代理具有開放代理,並限制某些應用通過某種網絡策略訪問其他代理。 – Rich