HTTP Authentification and CGI/Servlet

1. Identify yourself using HTTP Authentification

import java.net.*;
import java.io.*;

public class TestAuth {

  public static void main (String args[]){
    /*
    ** args[0]  is the URL protected
    ** args[1]  is the username
    ** args[2]  is the password
    */
    try {
      BufferedReader in = new BufferedReader(
          new InputStreamReader
             (openURLForInput(new URL(args[0]), args[1], args[2])));
      String line;
      while ((line = in.readLine()) != null) {
          System.out.println(line);
          }
    }
    catch (IOException e) {
      e.printStackTrace();
    }
  }

  public static InputStream openURLForInput
       (URL url, String uname, String pword)
       throws IOException
  {
    URLConnection conn = url.openConnection();
    conn.setDoInput (true);
    conn.setRequestProperty ("Authorization",
       userNamePasswordBase64(uname,pword));
    conn.connect ();
    return conn.getInputStream();
  }

  public static String userNamePasswordBase64
       (String username, String password)
  {
    return "Basic " + base64Encode (username + ":" + password);
  }

  private final static char base64Array [] = {
      'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
      'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
      'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
      'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
      'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
      'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
      'w', 'x', 'y', 'z', '0', '1', '2', '3',
      '4', '5', '6', '7', '8', '9', '+', '/'
  };



  private static String base64Encode (String string)    {
    String encodedString = "";
    byte bytes [] = string.getBytes ();
    int i = 0;
    int pad = 0;
    while (i < bytes.length) {
      byte b1 = bytes [i++];
      byte b2;
      byte b3;
      if (i >= bytes.length) {
         b2 = 0;
         b3 = 0;
         pad = 2;
         }
      else {
         b2 = bytes [i++];
         if (i >= bytes.length) {
            b3 = 0;
            pad = 1;
            }
         else
            b3 = bytes [i++];
         }
      byte c1 = (byte)(b1 >> 2);
      byte c2 = (byte)(((b1 & 0x3) << 4) | (b2 >> 4));
      byte c3 = (byte)(((b2 & 0xf) << 2) | (b3 >> 6));
      byte c4 = (byte)(b3 & 0x3f);
      encodedString += base64Array [c1];
      encodedString += base64Array [c2];
      switch (pad) {
       case 0:
         encodedString += base64Array [c3];
         encodedString += base64Array [c4];
         break;
       case 1:
         encodedString += base64Array [c3];
         encodedString += "=";
         break;
       case 2:
         encodedString += "==";
         break;
       }
      }
      return encodedString;
  }
}

A better alternative is the Authenticator class.

NOTE: a simple explanation about the base64 encoding principle is shown in this How-to.

An alternative way to Base64 encoding is to use the Base64 class in the sun.misc.* package.

sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();
String encodedUserPwd =
  encoder.encode("domain\\username:password".getBytes());
con.setRequestProperty("Proxy-Authorization", "Basic " + encodedUserPwd);

Use of the sun.* package is “discouraged” by sun and not formally supported. Those classes can be missing in your JDK release.

2. Talk to a CGI/Servlet

From the client point of view, there is no difference talking to CGI or Servlet. There is two ways to send a request to a CGI. The GET method contains encoded parameters in the URL. A typical URL talking to CGI using the GET method would be:

new URL("http://www.server.com/cgi-bin/acgi.pl?name=real&site=java+howto");

Here we calling a script called aCGI.pl (a PERL script) passing the parameters name and site. Parameters are encoded, spaces are changed to “+” and special character to hexadecimal using a 3-letter escape sequence. Each parameter is delimited by the character “&”. Habitually the encoding is done through the static method encode of the java.net.URLencoder class.

String theCGI = "http://www.server.com/cgi-bin/aCGI.pl?";
String encoded = "name=" + URLencoder.encode("Real Gagnon");
URL cgiurl = new URL(thecgi + encoded);

Once the URL is constructed, you call the CGI using the showDocument method (Applet).

getAppletContext().showDocument(cgiurl);

The CGI will process the result and produce a page to be displayed.

The POST method allows the programmer to manipulate the data received from the CGI. First a connection is made to the CGI, an OutputStream is open to send the parameters (if any). Then InputStream is created to receive the result.

String theCGI = "http://www.server.com/cgi-bin/aCGI.pl";
String encoded = "name=" + URLencoder.encode("Real Gagnon");
URL CGIurl = new URL(theCGI);

URLConnection c = CGIurl.openConnection();
c.setDoOutput(true);
c.setUseCaches(false);
c.setRequestProperty("content-type","application/x-www-form-urlencoded");
DataOutputStream out = new DataOutputStream(c.getOutputStream());
out.writeBytes(encoded);
out.flush(); out.close();

BufferedReader in =
   new BufferedReader(new InputStreamReader(c.getInputStream());

String aLine;
while ((aLine = in.readLine()) != null) {
   // data from the CGI
   System.out.println(aLine);
}

You can’t do some output then some input and do again some output. You must do all the output and then the input. There is no “dialog” between the client and the server. The client make a request and the server send back the result and close the connection.

Done! Happy Coding!

Related posts:

Java Program to Implement Stack using Two Queues
Supplier trong Java 8
Vấn đề Nhà sản xuất (Producer) – Người tiêu dùng (Consumer) và đồng bộ hóa các luồng trong Java
Java Program to Check if a Given Binary Tree is an AVL Tree or Not
Guava – Join and Split Collections
Java Program to Perform Uniform Binary Search
Jackson – Decide What Fields Get Serialized/Deserialized
Guide to the Volatile Keyword in Java
Java Program to Implement Ternary Search Algorithm
Receive email using IMAP
A Guide to the Java ExecutorService
Java Program to Perform the Sorting Using Counting Sort
Java Program to Use Boruvka’s Algorithm to Find the Minimum Spanning Tree
Java – Byte Array to Reader
List Interface trong Java
Function trong Java 8
Java Program to Find Nearest Neighbor for Dynamic Data Set
Java Program to Perform Right Rotation on a Binary Search Tree
Java Program to Find Number of Spanning Trees in a Complete Bipartite Graph
Java Program to Check Whether an Undirected Graph Contains a Eulerian Path
How to use the Spring FactoryBean?
LinkedHashSet trong Java hoạt động như thế nào?
Java Program to Test Using DFS Whether a Directed Graph is Strongly Connected or Not
Java Program to Find SSSP (Single Source Shortest Path) in DAG (Directed Acyclic Graphs)
Java Program to Check Whether Topological Sorting can be Performed in a Graph
The SpringJUnitConfig and SpringJUnitWebConfig Annotations in Spring 5
New Features in Java 8
Java Program to Find the Longest Subsequence Common to All Sequences in a Set of Sequences
Using Spring ResponseEntity to Manipulate the HTTP Response
Java Program to Find Path Between Two Nodes in a Graph
Java Program to Apply DFS to Perform the Topological Sorting of a Directed Acyclic Graph
So sánh Array và ArrayList trong Java