2011-08-31 8 views
2

우리는 JBoss에서 실행중인 응용 프로그램을 가지고 있습니다. 많은 설치에서 서버는 프록시를 통하지 않고 인터넷에 대한 액세스를 거부하는 방화벽 뒤에 있습니다. 이제 내 작업은 인증이 필요할 때이 프록시를 사용하는 방법을 찾는 것입니다.JBoss에서 프록시 액세스

프록시를 사용하도록 JBoss를 구성하면 -Dhttp.proxyHost=proxy_host -Dhttp.proxyPort=proxy_port에 아무런 문제가 없지만 사용자 이름과 암호를 나타내는 방법이 없습니다.

비 EJB 응용 프로그램에서는 ProxyAuthenticator가 Authenticator를 확장하는 곳인 Authenticator.setDefault(new ProxyAuthenticator("test", "test"))을 사용하여 성공했습니다. 그러나 이것은 JBoss에서 작동하지 않습니다.

하위 문제는 서버와 비 EJB 응용 프로그램이 프록시를 사용하지 않고 로컬 리소스에 액세스해야한다는 것입니다.

답변

1

마침내이 작업이 가능해졌습니다. Richs 게시물의 두 링크와 시행 착오를 거쳐 이제는 재구성되었습니다. 현재 기본 인증 만 구현했으며 앞으로 다른 인증 유형을 추가해야 할 것입니다.

큰 방해물은 -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

관련 문제