Featured Whitepapers
Newsletter sign-up
View all newsletters

Sign up for our technology specific newsletters.

Enterprise Java
Email Address:

Java Tip 46: Use Java 1.2's Authenticator class

Learn to access password-protected URLs with Java 1.2

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone

When surfing the 'Net using your favorite browser you encounter a URL that requires authentication from a proxy or HTTP server and are presented with the all-too-familiar screen demanding your username and password:

Accessing a URL like http://www.lombard.com/cgi-bin/Quotes/quote from a browser is not a problem because you can provide a username and password yourself. But from a Java program, a FileNotFoundException is thrown when you try to read from an InputStream associated with the URL.

User name and password dialog box

With Java 1.0 or 1.1, you can avoid this by posting the appropriate authentication string at connection time, but only if you know beforehand that the URL is protected. (Authorization: Basic username:password, where the basic authentication fields are encoded in base 64.) If you don't forsee that a document is protected, you won't even be able to read the content. (See "Java Tip 47: URL authentication revisited" for the solution to accessing password-protected URLs with Java 1.1 applets and applications.) Thankfully, Java 1.2 adds an Authenticator class to the java.net package that makes accessing password-protected URLs as easy as can be.

Now, in Java 1.2, you simply install an Authenticator, with Authenticator.setDefault(). Then, when authentication is necessary, the installed Authenticator's getPasswordAuthentication() method is called, and you return a PasswordAuthentication instance with the appropriate username and password. It's that easy.

The steps are shown below.

Step 1: Install Authenticator

Authenticator.setDefault (new MyAuthenticator ());


Step 2: Create Authenticator subclass

class MyAuthenticator extends Authenticator {  protected PasswordAuthentication getPasswordAuthentication() {
    return new PasswordAuthentication ("username", "password");
  }
}


The following program shows off this behavior in its entirety, offering its own authentication prompt dialog.

import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
public class URLPassword extends Frame {
  private TextField tf = new TextField();
  private TextArea  ta = new TextArea();
  public URLPassword() {
    super ("URL Password");
    // Install Authenticator
    Authenticator.setDefault (new MyAuthenticator ());
    // Setup screen
    add (tf, BorderLayout.NORTH);
    ta.setEditable(false);
    add (ta, BorderLayout.CENTER);
    tf.addActionListener (new ActionListener() {
      public void actionPerformed (ActionEvent e) {
        String s = tf.getText();
        if (s.length() != 0)
          ta.setText (fetchURL (s));
      }
    });
    addWindowListener (new WindowAdapter() {
      public void windowClosing (WindowEvent e) {
        dispose();
        System.exit(0);
      }
    });
  }
  private String fetchURL (String urlString) {
    StringWriter sw = new StringWriter();
    PrintWriter  pw = new PrintWriter(sw);
    try {
      URL url = new URL (urlString);
      InputStream content = (InputStream)url.getContent();
      BufferedReader in   = 
        new BufferedReader (new InputStreamReader (content));
      String line;
      while ((line = in.readLine()) != null) {
        pw.println (line);
      }
    } catch (MalformedURLException e) {
      pw.println ("Invalid URL");
    } catch (IOException e) {
      pw.println ("Error reading URL");
    }
    return sw.toString();
  }
  public static void main (String args[]) {
    Frame f = new URLPassword();
    f.setSize(300, 300);
    f.setVisible (true);
  }
  class MyAuthenticator extends Authenticator {
    protected PasswordAuthentication getPasswordAuthentication() {
      final Dialog jd = new Dialog (URLPassword.this, "Enter password", true);
      jd.setLayout (new GridLayout (0, 1));
      Label jl = new Label (getRequestingPrompt());
      jd.add (jl);
      TextField username = new TextField();
      username.setBackground (Color.lightGray);
      jd.add (username);
      TextField password = new TextField();
      password.setEchoChar ('*');
      password.setBackground (Color.lightGray);
      jd.add (password);
      Button jb = new Button ("OK");
      jd.add (jb);
      jb.addActionListener (new ActionListener() {
        public void actionPerformed (ActionEvent e) {
          jd.dispose();
        }
      });
      jd.pack();
      jd.setVisible(true);
      return new PasswordAuthentication (username.getText(), password.getText());
    }
  }
}

A follow-up tip - From Luis Blanco Gomez

Line 85 of the code, which is the return argument of the MyAuthenticator class, displays an error:

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comment
Login
Forgot your account info?
Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.
Resources
  • Authenticator documentation http://java.sun.com/products/jdk/1.2/docs/api/java.net.Authenticator.html
  • Swing's JEditorPane class, a simple HTML renderer http://java.sun.com/products/jfc/swingdoc-current/api/com.sun.java.swing.JEditorPane.html