How to make your Java applications work across proxies and firewalls?

Introduction

Java provides a rich API for networking and I/O. The initial releases of the JDK did not contain native support for proxies and firewall authentications -- however, as of J2SDK1.4, Java also provides native support for proxies and authentication. In this article, I will cover three mechanisms for making your Java applications proxy-aware -- the first two are high-level, but slightly less powerful methods, and the last one is a slighly lower-level but more powerful method.

Configuring your Java Runtime Environment to use proxies

Irrespective of which method you choose to use, you will have to configure the JRE to use proxies. This is done by setting the following System properties:

                // This is for HTTP Proxies
                System.getProperties().put("proxySet", "true");
                System.getProperties().put("proxyHost", "proxy.somedomain.org");
                System.getProperties().put("proxyPort", "3128");
                // This is for FTP Proxies
                defaultProperties.put( "ftpProxySet", "true" );
                defaultProperties.put( "ftpProxyHost", "proxy-host-name" );
                defaultProperties.put( "ftpProxyPort", "85" );
                // This is for SOCKS Proxies
                System.getProperties().setProperty("socksProxySet", "true");
                System.getProperties().setProperty("socksProxyHost", proxyServerName);
                System.getProperties().setProperty("socksProxyPort", proxyServerPort);
            

Java 2 Native Support

Java 2 has a native authentication framework which can be used to provide authentication for a wide range of services in a platform and protocol independent mechanism. This is done by providing Authenticator objects.

                import java.net.*;
                import java.io.*;
                public class TestProxy{
                public static final String CRLF = "/r/n";
                public TestProxy(){
                try{
                System.getProperties().put("proxySet", "true");
                System.getProperties().put("proxyHost", "proxy.domain.com");
                System.getProperties().put("proxyPort", "3128");
                Authenticator.setDefault(new MyAuthenticator());
                URL url = new URL("http://www.google.com");
                URLConnection conn = url.openConnection();
                }catch(Exception e){
                e.printStackTrace();
                }
                }
                public static void main(String args[]){
                TestProxy tp = new TestProxy();
                }
                }
                class MyAuthenticator extends Authenticator{
                protected PasswordAuthentication getPasswordAuthentication(){
                return new PasswordAuthentication("username", "password".toCharArray());
                }
                }

Using URLConnection API

Prior to Java 2, the SDK did not have native support for proxies. So, how does you go about making your old Java code proxy aware? Well, actually its not all that difficult. Basically, you have to play aorund with the HTTP headers yourself.

For an HTTP proxy, all HTTP requests should contain a Proxy-Authorization header ([??]) which stores the user name and password in a Base-64 encoding. You can use any base-64 encoder (and there are many available) -- for this example, I have used the encoder provided by Sun itself. However, it is not part of the standard JDK, so this code is not guaranteed to work. A simple implementation of a Base-64 encoder can be found here [??]

Having encoded the user name and password, you simply need to open a URLConnection, and set the request propert as shown below. Thats it, you're done!

                String authString = "username" + ":" + "password";
                String auth = "Basic " + new sun.misc.BASE64Encoder().encode(authString.getBytes());
                URL url = new URL("http://www.google.com");
                URLConnection conn = url.openConnection();
                conn.setRequestProperty("Proxy-Authorization", auth);

Using raw Socket Headers

The above two methods are nice and convinient, however, they are quite restrictive. For instance, consider the case of HTTP proxies. Both the methods discussed above will work only with the HTTP GET/PUT/POST methods. These work for most conventional web applications. But now suppose that you want to write a Jabber client which works behind firewalls. To do that, you will need a socket object which would work accross the proxy -- because you would like to do arbitrary read/writes to the server.

Many HTTP proxies allow this functionality via the HTTP CONNECT method. Basically, the proxy opens a socket to the server on your behalf and returns a handle of the socket to you. Any further traffic on that socket will be forward AS-IS without any inspection/modification by the proxy. For doing this in Java, you need to supply HTTP headers manually over a raw TCP socket. Here is how to do this:

                String authString = "username" + ":" + "password";
                String auth = "Basic " + new sun.misc.BASE64Encoder().encode(authString.getBytes());
                Socket socket = new Socket("vsnlproxy.iitk.ac.in", 3128);
                OutputStream out = socket.getOutputStream();
                out.write(("CONNECT toc.oscar.aol.com:9898 HTTP/1.1" + CRLF + "Host: toc.oscar.aol.com:9898" + CRLF).getBytes());
                out.write(("Proxy-Authorization: " + auth + CRLF).getBytes());
                out.write(CRLF.getBytes()); 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值